配置 bean知识点概览
1.配置形式:基于 XML 文件的方式、基于注解的方式
2.Bean 的配置方式:通过全类名(反射)、通过工厂方法(静态工厂方法 & 实例工厂方法)、FactoryBean
3.IOC 容器 BeanFactory & ApplicationContext 概述
4.依赖注入的方式:属性注入、构造器注入
5.注入属性值细节
6.自动装配
7.bean 之间的关系:继承、依赖
8.bean 的作用域:singleton、prototype、WEB 环境作用域
9.使用外部属性文件
10.spEL
11.IOC 容器中 Bean 的生命周期
12.Spring 4.x 新特性:泛型依赖注入
1.IOC 容器 BeanFactory & ApplicationContext 概述
1.1 两种类型的 IOC 容器
(1) BeanFactory: IOC 容器的基本实现,面向 Spring 本身
(2) ApplicationContext: 提供了更多的高级特性. 是 BeanFactory 的子接口,面向使用 Spring 框架的开发者
(3) 几乎所有的应用场合都直接使用 ApplicationContext 而非底层的 BeanFactory
1.2 ApplicationContext
(1) ApplicationContext 的主要实现类:
ClassPathXmlApplicationContext:从类路径下加载配置文件
FileSystemXmlApplicationContext:从文件系统中加载配置文件
(2) ConfigurableApplicationContext 扩展于 ApplicationContext,新增加两个主要方法:refresh()和close(), 具有启动、刷新和关闭上下文的能力
(3) WebApplicationContext 是专门为 WEB 应用而准备的,它允许从相对于 WEB 根目录的路径中完成初始化工作
2. 依赖注入的方式
2.1 属性注入(必须要有相应的setter)
<bean id="teacher" class="beans.teacher">
<property name="name" value="han"></property>
<property name="age" value="21"></property>
<property name="pay" value="5000"></property>
</bean>
2.2 构造器注入(必须要有相应的构造器)
<bean id="teacher2" class="beans.teacher">
<constructor-arg value="t1" index="0"></constructor-arg>
<constructor-arg value="20" type="java.lang.Integer"></constructor-arg>
</bean>
2.3 工厂方法注入(了解)
3.注入属性值的细节
3.1 注入内容中有特殊字符
<bean id="teacher3" class="beans.teacher">
<constructor-arg>
<value type="java.lang.String"><![CDATA[<一个带特殊字符的名字>]]></value>
</constructor-arg>
3.2 建立Bean之间的连接关系(ref)
<bean id="Pet" class="beans.Pet">
<property name="name" value="dog"></property>
<property name="age" value="2"></property>
</bean>
<bean id="Person" class="beans.Person">
<property name="name" value="张三"></property>
<property name="age" value="20"></property>
<!-- 通过 ref 属性值指定当前属性指向哪一个 bean! -->
<property name="pet" ref="Pet"></property>
</bean>
3.3 内部类
<bean id="Person2" class="beans.Person">
<property name="name" value="李四"></property>
<property name="age" value="20"></property>
<!--内部 bean,类似于匿名内部类对象,不能被外部的bean来引用-->
<property name="pet">
<bean class="beans.Pet">
<property name="name" value="Cat"></property>
<property name="age" value="3"></property>
</bean>
</property>
</bean>
3.4 的使用
<bean id="Person3" class="beans.Person">
<property name="name" value="李四"></property>
<property name="age" value="20"></property>
<property name="pet"><null/></property>
</bean>
3.5 级联属性(了解)
<bean id="Person4" class="beans.Person">
<property name="name" value="李四"></property>
<property name="age" value="20"></property>
<property name="pet" ref="Pet"></property>
<!--需要先初始化级联属性,才能为其赋值-->
<property name="pet.name" value="lion"></property>
</bean>
3.6 集合属性
3.6.1 List()
<bean id="rich" class="beans.RichMan">
<property name="name" value="yun"></property>
<property name="pets">
<!--在bean中为list属性的私有变量-->
<list>
<ref bean="Pet"/>
<ref bean="Pet2"/>
</list>
</property>
</bean>
3.6.2 Map(
<bean id="poor" class="beans.PoorMan">
<property name="name" value="me"></property>
<property name="map">
<!--在bean中为map属性的私有变量-->
<map>
<entry key="A" value-ref="Pet"/>
<entry key="B" value-ref="Pet2"/>
</map>
</property>
</bean>
3.6.3 Properties()
<bean id="dataSource" class="beans.DataSource">
<!--在bean中为properties属性的私有变量-->
<property name="properties">
<props>
<prop key="username">root</prop>
<prop key="password">LF@0827</prop>
<prop key="url">jdbc:mysql://localhost:3306/MyBatis?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC</prop>
<prop key="driver">com.mysql.cj.jdbc.Driver</prop>
</props>
</property>
</bean>
3.7 声明集合类型的 bean
<util:list id="Pets">
<ref bean="Pet"/>
<ref bean="Pet2"/>
</util:list>
3.8 p命名空间
3.8.1 在xml文件中导入p
在xml文件的头部加入
xmlns:context="http://www.springframework.org/schema/context"
xmlns:p="http://www.springframework.org/schema/p"
使用
<bean id="teacher0" class="beans.teacher" p:name="li"></bean>
4.自动装配(了解)
byType: 根据类型进行自动装配,但要求IOC容器中只有一个类型对应的bean,若有多个则无法完成自动装配.
byName: 若属性名和某一个bean的id名一致,即可完成自动装配,若没有id一致的,则无法完成自动装配
<bean id="pet" class="beans.Pet">
<property name="name" value="dog"></property>
<property name="age" value="2"></property>
</bean>
<bean id="Person" class="beans.Person" p:name="张三" autowire="byName"></bean>
5.继承与依赖
5.1 继承(使用bean的parent选择继承)
<bean id="Person1" class="beans.Person" p:name="李四" p:age="20"></bean>
<bean id="Person2" p:name="王五" parent="Person1" ></bean>
5.2 抽象Bean(把父Bean当模板使用)
<bean id="Person1" class="beans.Person" p:age="20" abstract="true"></bean>
<bean id="Person2" p:name="王五" parent="Person1" ></bean>
5.3 依赖(使用bean的depends-on依赖,如果依赖不存在,则不能初始化)
<bean id="Pet" class="beans.Pet" p:name="pig" p:age="1"></bean>
<bean id="Person3" class="beans.Person" p:name="憨憨" p:age="20" p:pet-ref="Pet" depends-on="Pet"></bean>
6.Bean的作用域(使用bean的scope指定作用域)
prototype: 原型的. 每次调用getBean方法都会返回一个新的bean. 且在第一次调用 getBean 方法时才创建实例
singleton: 单例的. 每次调用getBean方法都会返回同一个 bean. 且在 IOC 容器初始化时即创建 bean 的实例. 默认值
7.使用外部属性文件
db.xml
<!-- 导入外部的资源文件 -->
<context:property-placeholder location="classpath:db.properties"/>
<!--配置properties-->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
<property name="url" value="${url}"/>
<property name="driverClassName" value="${driverClassName}"/>
</bean>
db.properties配置文件
username=root
password=LF@0827
url=jdbc:mysql://localhost:3306/ttms?characterEncoding=UTF8&serverTimezone=UTC
driverClassName=com.mysql.jdbc.Driver
8.SpEL(相当于EL表达式)
(1) 通过bean的id对bean进行引用
(2) 调用方法以及引用对象中的属性
(3) 计算表达式的值
(4) 正则表达式的匹配
9.Bean的生命周期
(1) 通过构造器或工厂方法创建Bean实例
(2) 为Bean的属性设置值和对其他Bean的引用
(3) 将Bean实例传递给Bean后置处理器的postProcessBeforeInitialization 方法
(4) 调用Bean的初始化方法
(5) 将Bean实例传递给Bean后置处理器的postProcessAfterInitialization方法
(6) Bean的使用
(7) 当容器关闭时,调用Bean的销毁方法
bean.xml
<bean id="life" class="beans.life" init-method="init" destroy-method="destory">
<property name="name" value="一个bean"/>
</bean>
<!-- 配置 bean 后置处理器: 不需要配置 id 属性, IOC 容器会识别到他是一个 bean 后置处理器, 并调用其方法 -->
<bean class="beans.MyBeanPostProcessor"></bean>
bean
public class life {
private String name;
public life(){
System.out.println("无参构造--life");
}
public life(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void init(){
System.out.println("bean的初始化");
}
public void destory(){
System.out.println("bean的销毁");
}
@Override
public String toString() {
return "life{" +
"name='" + name + '\'' +
'}';
}
}
后置处理器
public class MyBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("bean初始化之前");
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("bean初始化之后");
return bean;
}
}
10.工厂方法配置Bean(了解)
10.1 静态工厂方法(一个类中有一个静态方法, 可以返回一个类的实例)
(1) class 中指定静态工厂方法的全类名,
(2) factory-method 中指定静态工厂方法的方法名
(3) constructor-arg 子节点为静态工厂方法指定参数
工厂
public class staticTeacherFactory {
private static Map<String,teacher> teachers = new HashMap<>();
static {
teachers.put("张三",new teacher("张三",20));
teachers.put("李四",new teacher("李四",21));
teachers.put("王五",new teacher("王五",19));
}
public static teacher getTeacher(String name){
return teachers.get(name);
}
}
Factory.xml
<bean id="factory" class="beans.staticTeacherFactory" factory-method="getTeacher">
<constructor-arg value="张三"/>
</bean>
10.2 实例工厂方法(需要创建工厂对象, 再调用工厂的非静态方法返回实例)
(1) 创建工厂对应的 bean
(2) 用实例工厂方法来创建 bean 实例
(3) constructor-arg 执行调用工厂方法需要传入的参数
工厂
public class InstanceTeacherFactory {
private Map<String,teacher> teachers;
public InstanceTeacherFactory(){
teachers = new HashMap<>();
teachers.put("张三",new teacher("张三",2000));
teachers.put("李四",new teacher("李四",2100));
teachers.put("王五",new teacher("王五",1900));
}
public teacher getTeacher(String name){
return teachers.get(name);
}
}
Factory.xml
<bean id="teacher" factory-bean="instanceFactory" factory-method="getTeacher">
<constructor-arg value="李四"/>
</bean>
11.FactoryBean配置Bean(了解)
(1) 必须实现 FactoryBean<T>接口的实现类
(2) 必须继承其三个方法
bean
public class teacherFactoryBean implements FactoryBean<teacher> {
//是否为单实例
@Override
public boolean isSingleton() {
return true;
}
//返回Bean的对象
@Override
public teacher getObject() throws Exception {
return new teacher("憨憨",3000);
}
//返回Bean的类型
@Override
public Class<?> getObjectType() {
return teacher.class;
}
}
Factory.xml
<bean id="factoryBean" class="beans.teacherFactoryBean"></bean>