spring
spring概述
1 spring是什么
Spring 是分层的 Java SE/EE 应用 full-stack 轻量级开源框架,以 IoC(Inverse Of Control: 反转控制)和 AOP(Aspect Oriented Programming:面向切面编程)为内核,提供了展现层 Spring MVC 和持久层 Spring JDBC 以及业务层事务管理等众多的企业级应用技术,还能整合开源世界众多 著名的第三方框架和类库,逐渐成为使用最多的 Java EE 企业应用开源框架。
2 spring的两大核心
Core Container 核心容器 IOC
单例 只创建一次 类成员只初始化一次
多例 对象被创建多次 执行效率没有单例对象高
IOC
创建对象的权利交给框架。包含依赖注入DI和依赖查找。
使用Spring的IOC解决程序耦合
基于XML的配置
1 新建bean.xml
<?xml version="1.0" encoding="UTF-8"?>
beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- bean 标签:用于配置让 spring 创建对象,并且存入 ioc 容器之中 id 属性:对象的唯一标识。 class 属性:指定要创建对象的全限定类名 -->
<!-- 配置 service --> <bean id="accountService" class="com.itheima.service.impl.AccountServiceImpl"> </bean>
<!-- 配置 dao --> <bean id="accountDao" class="com.itheima.dao.impl.AccountDaoImpl"></bean>
public static void main(String[] args) {
// 1.使用 ApplicationContext 接口,就是在获取 spring 容器
ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
//2.根据 bean 的 id 获取对象
IAccountService aService = (IAccountService) ac.getBean("accountService");
System.out.println(aService);
IAccountDao aDao = (IAccountDao) ac.getBean("accountDao"); System.out.println(aDao);
}
基于XML的IOC细节
1 BeanFactory和 ApplicationContext 的区别
BeanFactory 才是 Spring 容器中的顶层接口。
ApplicationContext 是它的子接口。
BeanFactory 和 ApplicationContext 的区别: 创建对象的时间点不一样。
ApplicationContext:单例对象创建 实际开发采用 构建核心容器是创建对象采取的思想是 立即加载的方式,只要一读取完马上创建配置文件中的配置对象。
只要一读取配置文件,默认情况下就会创建对象。
BeanFactory:多例对象使用
构建核心容器是创建对象采取的思想是 延迟加载的方式,什么时候根据ID获取对象什么时候创建对象 什么使用什么时候创建对象。
2 ApplicationContext 接口的实现类
ClassPathXmlApplicationContext: 可以加载类路径下的配置文件 要求配置文件必须在类路径下 不在的加载不了 实际开发使用
FileSystemXmlApplicationContext: 可以加载磁盘任意路径下的配置路径 必须有访问权限
AnnotationConfigApplicationContext: 用于读取注解创建容器
IOC 中 bean 标签和管理对象细节
创建bean的三种方式
1 第一种方式 使用默认构造函数创建在spring的配置文件使用bean标签 配以ID和class属性 且没有其他的标签 采用默认的构造函数创建bean对象如果没有默认的构造函数则对象不能创建
<bean id="accountService"class="com.service.impl.AccountServiceImpl"></bean>
2
<!-- 第二种方式 使用普通工厂中的方法创建对象 (使用某个类中的方法创建对象并存入spring容器)-->
<!-- <bean id="instanceFactory" class="com.factory.InstanceFactory"></bean>-->
<!-- <bean id="accountService" factory-bean="instanceFactory" factory-method="getAccountServiceInterface"></bean>-->
// 模拟工厂类 该类可能存在于jar包 无法修改源码来提供默认构造函数
public class InstanceFactory {
public AccountServiceInterface getAccountServiceInterface() {
return new AccountServiceImpl();
}
}
3
<!-- 第三个方式 使用静态工厂中的静态方法创建对象 使用某个类中的静态方法创建对象 并存入spring容器-->
<!-- <bean id="accountService" class="com.factory.StaticFactory" factory-method="getAccountServiceInterface"></bean>-->
public class StaticFactory {
public static AccountServiceInterface getAccountServiceInterface() {
return new AccountServiceImpl();
}
}
bean的作用范围调整
<!-- bean的作用范围调整
scope属性 用于指定bean的作用范围
取值 singleton 单例 默认值 常用
prototype 多例 常用
request 作用于web应用的请求范围
session 作用于web应用的会话范围
global-session 作用于集群环境的会话范围(全局会话范围)当不是集群环境就是session
-->
<!-- <bean id="accountService" class="com.service.impl.AccountServiceImpl" scope="prototype"></bean>-->
负载均衡 global-session含义
bean对象的生命周期
<!-- bean对象的生命周期
单例对象
出生 当容器创建时对象出生
活着 容器还在对象一直存在
死亡 容器销毁 对象销毁
总结 单例对象的生命周期和容器相同
多例对象
出生 当使用对象是spring框架创建
活着 对象使用过程中一直存在
死亡 对象长时间不用且没有别的对象引用 Java垃圾回收器回收
-->
<bean id="accountService" class="com.service.impl.AccountServiceImpl" scope="prototype" init-method="init" destroy-method="destroy">
</bean>
spring 的依赖注入
依赖注入:Dependency Injection。它是 spring 框架核心 ioc 的具体实现。 我们的程序在编写时,通过控制反转,把对象的创建交给了 spring,但是代码中不可能出现没有依赖的情况。 ioc 解耦只是降低他们的依赖关系,但不会消除。例如:我们的业务层仍会调用持久层的方法。 那这种业务层和持久层的依赖关系,在使用 spring 之后,就让 spring 来维护了。 简单的说,就是坐等框架把持久层对象传入业务层,而不用我们自己去获取。
<!-- Spring的依赖注入
IOC的作用 降低程序间的耦合
依赖关系管理
交给spring来维护
在当前类需要用到其他类的对象 由spring为我们提供 我们只需在配置文件中说明
依赖关系的维护:
就是依赖注入
依赖注入:
能注入的数据:基本类型和String
其他的bean类型(配置文件中或者注解配置过的bean)
复杂类型/集合类型
注入的方式:
第一种:使用构造函数
第二种:使用set方法
第三种:使用注解-->
构造函数注入
<!-- 构造函数注入: 很少使用
使用标签: constructor-arg
出现的位置 bean标签内部
标签属性:
type 用于指定要注入的数据的数据类型 该数据类型也是构造函数中某个或者某些参数类型
index 用于指定要注入的数据给构造函数在指定索引位置参数赋值。索引的位置从0开始
name 用于指定给构造函数中指定名称的参数赋值 常用的
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++用于指定给构造函数中参数赋值
ref 用于指定其他bean类型数据。指的是spring的IOC核心容器中出现过得bean对象
value 用于给基本类型和string类型的数据
优势:
获取bean对象注入数据是必须的操作否则无法创建成功。
劣势:
改变bean对象实例化方式 使创建对象如果用不到这些数据也必须提供
-->
<bean id="accountService" class="com.service.impl.AccountServiceImpl">
<constructor-arg name="name" value="test"></constructor-arg>
<constructor-arg name="age" value="18"></constructor-arg>
<constructor-arg name="date" ref="now"></constructor-arg>
</bean>
<!-- 配置日期对象-->
<bean id="now" class="java.util.Date"></bean>
// 账户的业务层实现类
public class AccountServiceImpl implements AccountServiceInterface {
// 经常变化的数据 并不适用于注入的方式
private String name;
private Integer age;
private Date date;
public AccountServiceImpl(String name,
Integer age,
Date date) {
this.age = age;
this.date = date;
this.name = name;
}
public void saveAccount() {
System.out.println("执行"+age+date+name);
}
}
setter方法
<!-- setter方法 常用、、、、、、、、、、、、、、、、
涉及的标签:property
位置:bean标签内部
标签属性:
name 用于指定注入时所调用的sett方法名称
ref 用于指定其他bean类型数据。指的是spring的IOC核心容器中出现过得bean对象
value 用于给基本类型和string类型的数据
优势:
创建对象时没有明确的限制,可以直接使用默认构造函数。
劣势:
如果某个成员必须有值,则set方法无法保证一定注入.(获取对象可能set方法没有执行)
-->
<bean id="accountService2" class="com.service.impl.AccountServiceImpl2">
<property name="userName" value="test"></property>
<property name="age" value="11"></property>
<property name="date" ref="now"></property>
</bean>
public class AccountServiceImpl2 implements AccountServiceInterface {
// 经常变化的数据 并不适用于注入的方式
private String name;
private Integer age;
private Date date;
public void setUserName(String name) {
this.name = name;
}
public void setAge(Integer age) {
this.age = age;
}
public void setDate(Date date) {
this.date = date;
}
public void saveAccount() {
System.out.println("执行"+age+date+name);
}
}
复杂/集合类型注入
<!-- 复杂/集合类型注入
给list结构集合的标签
list Array set
给map结构集合的标签
map props
结构相同 标签可以互换
-->
<bean id="accountService3" class="com.service.impl.AccountServiceImpl3">
<property name="myStr">
<array>
<value>AAA</value>
<value>BBB</value>
</array>
</property>
<property name="myList">
<list>
<value>AAA</value>
<value>BBB</value>
</list>
</property>
<property name="mySet">
<set>
<value>AAA</value>
<value>BBB</value>
</set>
</property>
<property name="myMap">
<map>
<entry key="AAA" value="aaaa"></entry>
<entry key="BBBB"><value>bbbbb</value></entry>
</map>
</property>
<property name="properties">
<props>
<prop key="eeeee">ffffff</prop>
</props>
</property>
</bean>
public class AccountServiceImpl3 implements AccountServiceInterface {
private String[] myStr;
private List<String> myList;
private Set<String> mySet;
private Map<String, String> myMap;
private Properties properties;
public void setMyStr(String[] myStr) {
this.myStr = myStr;
}
public void setMyList(List<String> myList) {
this.myList = myList;
}
public void setMySet(Set<String> mySet) {
this.mySet = mySet;
}
public void setMyMap(Map<String, String> myMap) {
this.myMap = myMap;
}
public void setProperties(Properties properties) {
this.properties = properties;
}
public void saveAccount() {
System.out.println(Arrays.toString(myStr));
System.out.println(myList);
System.out.println(myMap);
System.out.println(mySet);
System.out.println(properties);
}
}