Spring系列(20-22)
二十、注解实现依赖注入(@Autowired、@Resource、@Primary、@Qulifier)
1、@Autowired:注入依赖对象
@Target({ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.PARAMETER,
ElementType.FIELD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Autowired {
/**
* Declares whether the annotated dependency is required.
* <p>Defaults to {@code true}.
*/
boolean required() default true;
}@Autowire查找候选者的过程
@Autowired标注在方法上或者方法参数上面:假定参数类型为为一个自定义的普通的类型,候选者查找过程如下:
将指定类型的所有bean注入到Collection中
@Autowired private List<IService> services;
将指定类型的所有bean注入到Map中
@Autowired private Map<String, IService> serviceMap;
2、@Resource:注意依赖对象
javax.annotation.Resource
@Target({TYPE, FIELD, METHOD})
@Retention(RUNTIME)
public @interface Resource {
String name() default "";
// 其他不常用的参数省略
}@Resource查找候选者的过程
@Resource标注在方法上或者方法参数上面:假定参数类型为为一个自定义的普通的类型,候选者查找过程如下:
将指定类型的所有bean注入到Collection中
@Resource private List<IService> services;
将指定类型的所有bean注入到Map中
@Resource private Map<String, IService> serviceMap;
3、Qualifier:限定符
@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER,
ElementType.TYPE, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Qualifier {
String value() default "";
}4、@Primary:设置为主要候选者
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Primary {
}方式1:在类上标注@Component注解,此时可以配合@Primary,标注这个bean为主要候选者方式2:在配置文件中使用@Bean注解标注方法,来注册bean,可以在@Bean标注的方法上加上@Primary,标注这个bean为主要候选bean。
5、泛型注入
public class UserModel {}
public class OrderModel {}
// 泛型接口
public interface IDao<T> {}
// 泛型接口实现类
@Component
public class UserDao implements IDao<UserModel> {// 指定泛型的类型为UserMod
}
@Component
public class OrderDao implements IDao<OrderModel> {// 指定泛型的类型为OrderModel
}定义一个泛型service
public class BaseService<T> {
@Autowired
private IDao<T> dao;
public IDao<T> getDao() {
return dao;
}
public void setDao(IDao<T> dao) {
this.dao = dao;
}
}定义泛型service实现类
@Component
public class UserService extends BaseService<UserModel> {// 指定注入的类型UserModel
}
@Component
public class OrderService extends BaseService<OrderModel> {// 指定注入的类型OrderModel
}1、@Scope
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Scope {
@AliasFor("scopeName")
String value() default "";
@AliasFor("value")
String scopeName() default "";
ScopedProxyMode proxyMode() default ScopedProxyMode.DEFAULT;
}@Component
@Scope(ConfigurableBeanFactory.SCOPE_SINGLETON)
public class ServiceA {
}ConfigurableBeanFactory接口中定义了几个作用域相关的常量,可以直接拿来使用,如:
String SCOPE_SINGLETON = "singleton"; String SCOPE_PROTOTYPE = "prototype";
2、@DependsOn:指定当前bean依赖的bean
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DependsOn {
String[] value() default {};
}3、@ImportResource:配置类中导入bean定义的配置文件
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
public @interface ImportResource {
@AliasFor("locations")
String[] value() default {};
@AliasFor("value")
String[] locations() default {};
Class<? extends BeanDefinitionReader> reader() default BeanDefinitionReader.class;
}value和locations效果一样,只能配置其中一个,是一个String类型的数组,用来指定需要导入的配置文件的路径。
reader:用来指定bean定义的读取器,目前我们知道的配置bean的方式有xml文件的方式,注解的方式,其实还有其他的方式,比如properties文件的方式,如果用其他的方式,你得告诉Spring具体要用那种解析器去解析这个bean配置文件,这个解析器就是BeanDefinitionReader。
资源文件路径的写法
以classpath:开头:检索目标为当前项目的classes目录。
以classpath*:开头:检索目标为当前项目的classes目录,以及项目中所有jar包中的目录,如果你确定jar不是检索目标,就不要用这种方式,由于需要扫描所有jar包,所以速度相对于第一种会慢一些。
// 文件通配符的方式 classpath:/com/javacode2018/lesson001/demo27/test5/beans-*.xml // 目录通配符的方式 classpath:/com/javacode2018/lesson001/demo27/*/beans-*.xml // 递归任意子目录的方式 classpath:/com/javacode2018/**/beans-*.xml
4、@Lazy:延迟初始化
@Target({ElementType.TYPE, ElementType.METHOD, ElementType.CONSTRUCTOR,
ElementType.PARAMETER, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Lazy {
boolean value() default true;
}二十二、Bean生命周期详解
1、Bean元信息配置阶段
Bean信息定义4种方式
API的方式
Xml文件方式
properties文件的方式
注解的方式
API方式
BeanDefinition接口:bean定义信息接口
public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement {
/**
* 设置此bean的父bean名称(对应xml中bean元素的parent属性)
*/
void setParentName(@Nullable String parentName);
/**
* 返回此bean定义时指定的父bean的名称
*/
@Nullable
String getParentName();
/**
* 指定此bean定义的bean类名(对应xml中bean元素的class属性)
*/
void setBeanClassName(@Nullable String beanClassName);
/**
* 返回此bean定义的当前bean类名
* 注意,如果子定义重写/继承其父类的类名,则这不一定是运行时使用的实际类名。此外,这可能只
是调用工厂方法的类,或者在调用方法的工厂bean引用的情况下,它甚至可能是空的。因此,不要认为这是运
行时的最终bean类型,而只将其用于单个bean定义级别的解析目的。
*/
@Nullable
String getBeanClassName();
/**
* 设置此bean的生命周期,如:singleton、prototype(对应xml中bean元素的scope属性)
*/
void setScope(@Nullable String scope);
/**
* 返回此bean的生命周期,如:singleton、prototype
*/
@Nullable
String getScope();
/**
* 设置是否应延迟初始化此bean(对应xml中bean元素的lazy属性)
*/
void setLazyInit(boolean lazyInit);
/**
* 返回是否应延迟初始化此bean,只对单例bean有效
*/
boolean isLazyInit();
/**
* 设置此bean依赖于初始化的bean的名称,bean工厂将保证dependsOn指定的bean会在当前bean初
始化之前先初始化好
*/
void setDependsOn(@Nullable String... dependsOn);
/**
* 返回此bean所依赖的bean名称
*/
@Nullable
String[] getDependsOn();
/**
* 设置此bean是否作为其他bean自动注入时的候选者
* autowireCandidate
*/
void setAutowireCandidate(boolean autowireCandidate);
/**
* 返回此bean是否作为其他bean自动注入时的候选者
*/
boolean isAutowireCandidate();
/**
* 设置此bean是否为自动注入的主要候选者
* primary:是否为主要候选者
*/
void setPrimary(boolean primary);
/**
* 返回此bean是否作为自动注入的主要候选者
*/
boolean isPrimary();
/**
* 指定要使用的工厂bean(如果有)。这是要对其调用指定工厂方法的bean的名称。
* factoryBeanName:工厂bean名称
*/
void setFactoryBeanName(@Nullable String factoryBeanName);
/**
* 返回工厂bean名称(如果有)(对应xml中bean元素的factory-bean属性)
*/
@Nullable
String getFactoryBeanName();
/**
* 指定工厂方法(如果有)。此方法将使用构造函数参数调用,如果未指定任何参数,则不使用任何参
数调用。该方法将在指定的工厂bean(如果有的话)上调用,或者作为本地bean类上的静态方法调用。
* factoryMethodName:工厂方法名称
*/
void setFactoryMethodName(@Nullable String factoryMethodName);
/**
* 返回工厂方法名称(对应xml中bean的factory-method属性)
*/
@Nullable
String getFactoryMethodName();
/**
* 返回此bean的构造函数参数值
*/
ConstructorArgumentValues getConstructorArgumentValues();
/**
* 是否有构造器参数值设置信息(对应xml中bean元素的<constructor-arg />子元素)
*/
default boolean hasConstructorArgumentValues() {
return !getConstructorArgumentValues().isEmpty();
}
/**
* 获取bean定义是配置的属性值设置信息
*/
MutablePropertyValues getPropertyValues();
/**
* 这个bean定义中是否有属性设置信息(对应xml中bean元素的<property />子元素)
*/
default boolean hasPropertyValues() {
return !getPropertyValues().isEmpty();
}
/**
* 设置bean初始化方法名称
*/
void setInitMethodName(@Nullable String initMethodName);
/**
* bean初始化方法名称
*/
@Nullable
String getInitMethodName();
/**
* 设置bean销毁方法的名称
*/
void setDestroyMethodName(@Nullable String destroyMethodName);
/**
* bean销毁的方法名称
*/
@Nullable
String getDestroyMethodName();
/**
* 设置bean的role信息
*/
void setRole(int role);
/**
* bean定义的role信息
*/
int getRole();
/**
* 设置bean描述信息
*/
void setDescription(@Nullable String description);
/**
* bean描述信息
*/
@Nullable
String getDescription();
/**
* bean类型解析器
*/
ResolvableType getResolvableType();
/**
* 是否是单例的bean
*/
boolean isSingleton();
/**
* 是否是多列的bean
*/
boolean isPrototype();
/**
* 对应xml中bean元素的abstract属性,用来指定是否是抽象的
*/
boolean isAbstract();
/**
* 返回此bean定义来自的资源的描述(以便在出现错误时显示上下文)
*/
@Nullable
String getResourceDescription();
@Nullable
BeanDefinition getOriginatingBeanDefinition();
}AttributeAccessor
BeanMetadataElement
AttributeAccessor接口:属性访问接口
public interface AttributeAccessor {
/**
* 设置属性->值
*/
void setAttribute(String name, @Nullable Object value);
/**
* 获取某个属性对应的值
*/
@Nullable
Object getAttribute(String name);
/**
* 移除某个属性
*/
@Nullable
Object removeAttribute(String name);
/**
* 是否包含某个属性
*/
boolean hasAttribute(String name);
/**
* 返回所有的属性名称
*/
String[] attributeNames();
}BeanMetadataElement接口
public interface BeanMetadataElement {
@Nullable
default Object getSource() {
return null;
}
}Definition分类
RootBeanDefinition类:表示根bean定义信息
ChildBeanDefinition类:表示子bean定义信息
GenericBeanDefinition类:通用的bean定义信息
ConfigurationClassBeanDefinition类:表示通过配置类中@Bean方法定义bean信息
AnnotatedBeanDefinition接口:表示通过注解的方式定义的bean信息
BeanDefinitionBuilder:构建BeanDefinition的工具类
案例
public class Car {
private String name;
//此处省略了get和set方法 toString方法
}组装一个有属性的bean
@Test
public void test2() {
//指定class
BeanDefinitionBuilder beanDefinitionBuilder =
BeanDefinitionBuilder.rootBeanDefinition(Car.class.getName());
// 调用addPropertyValue给Car中的name设置值
beanDefinitionBuilder.addPropertyValue("name", "奥迪");
//获取BeanDefinition
BeanDefinition carBeanDefinition = beanDefinitionBuilder.getBeanDefinition();
System.out.println(carBeanDefinition);
//创建spring容器
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
//调用registerBeanDefinition向容器中注册bean,bean的名称为car
factory.registerBeanDefinition("car", carBeanDefinition);
Car bean = factory.getBean("car", Car.class);
System.out.println(bean);
}组装一个有依赖关系的bean
public class User {
private String name;
private Car car;
//此处省略了get和set方法 toString方法
}@Test
public void test3() {
// 先创建car这个BeanDefinition
BeanDefinition carBeanDefinition = BeanDefinitionBuilder.rootBeanDefinition(Car.class.getName()).addPropertyValue("name", "奥迪").getBeanDefinition();
// 创建User这个BeanDefinition
BeanDefinition userBeanDefinition = BeanDefinitionBuilder
.rootBeanDefinition(User.class.getName())
.addPropertyValue("name", "路人甲Java")
// 注入依赖的bean,需要使用addPropertyReference方法,2个参数,第一个为属性的名称,第二个为需要注入的bean的名称
.addPropertyReference("car", "car").getBeanDefinition();
// 创建Spring容器
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
// 调用registerBeanDefinition向容器中注册bean
factory.registerBeanDefinition("car", carBeanDefinition);
factory.registerBeanDefinition("user", userBeanDefinition);
System.out.println(factory.getBean("car"));
System.out.println(factory.getBean("user"));
}2个有父子关系的bean
@Test
public void test4() {
//先创建car这个BeanDefinition
BeanDefinition carBeanDefinition1 = BeanDefinitionBuilder.genericBeanDefinition(Car.class).addPropertyValue("name", "保时捷").getBeanDefinition();
BeanDefinition carBeanDefinition2 = BeanDefinitionBuilder.genericBeanDefinition().setParentName("car1"). // 设置父bean的名称为car1
getBeanDefinition();
//创建Spring容器
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
//调用registerBeanDefinition向容器中注册bean
//注册car1->carBeanDefinition1
factory.registerBeanDefinition("car1", carBeanDefinition1);
//注册car2->carBeanDefinition2
factory.registerBeanDefinition("car2", carBeanDefinition2);
//从容器中获取car1
System.out.println(String.format("car1->%s", factory.getBean("car1")));
//从容器中获取car2
System.out.println(String.format("car2->%s", factory.getBean("car2")));
}通过api设置(Map、Set、List)属性
public class CompositeObj {
private String name;
private Integer salary;
private Car car1;
private List<String> stringList;
private List<Car> carList;
private Set<String> stringSet;
private Set<Car> carSet;
private Map<String, String> stringMap;
private Map<String, Car> stringCarMap;
//此处省略了get和set方法 toString方法
}@Test
public void test5() {
// 定义car1
BeanDefinition car1 = BeanDefinitionBuilder.genericBeanDefinition(Car.class)
.addPropertyValue("name", "奥迪").getBeanDefinition();
// 定义car2
BeanDefinition car2 = BeanDefinitionBuilder.genericBeanDefinition(Car.class)
.addPropertyValue("name", "保时捷").getBeanDefinition();
// 定义CompositeObj这个bean
// 创建stringList这个属性对应的值
ManagedList<String> stringList = new ManagedList<>();
stringList.addAll(Arrays.asList("java高并发系列", "mysql系列", "maven高手系列"));
// 创建carList这个属性对应的值,内部引用其他两个bean的名称[car1,car2]
ManagedList<RuntimeBeanReference> carList = new ManagedList<>();
// RuntimeBeanReference:用来表示bean引用类型,类似于xml中的ref
carList.add(new RuntimeBeanReference("car1"));
carList.add(new RuntimeBeanReference("car2"));
//创建stringList这个属性对应的值
ManagedSet<String> stringSet = new ManagedSet<>();
stringSet.addAll(Arrays.asList("java高并发系列", "mysql系列", "maven高手系列"));
//创建carSet这个属性对应的值,内部引用其他两个bean的名称[car1,car2]
ManagedList<RuntimeBeanReference> carSet = new ManagedList<>();
carSet.add(new RuntimeBeanReference("car1"));
carSet.add(new RuntimeBeanReference("car2"));
//创建stringMap这个属性对应的值
ManagedMap<String, String> stringMap = new ManagedMap<>();
stringMap.put("系列1", "java高并发系列");
stringMap.put("系列2", "Maven高手系列");
stringMap.put("系列3", "mysql系列");
ManagedMap<String, RuntimeBeanReference> stringCarMap = new ManagedMap<>();
stringCarMap.put("car1", new RuntimeBeanReference("car1"));
stringCarMap.put("car2", new RuntimeBeanReference("car2"));
//下面我们使用原生的api来创建BeanDefinition
GenericBeanDefinition compositeObj = new GenericBeanDefinition();
compositeObj.setBeanClassName(CompositeObj.class.getName());
compositeObj.getPropertyValues().add("name", "路人甲Java").
add("salary", 50000).
add("car1", new RuntimeBeanReference("car1")).
add("stringList", stringList).
add("carList", carList).
add("stringSet", stringSet).
add("carSet", carSet).
add("stringMap", stringMap).
add("stringCarMap", stringCarMap);
//将上面bean 注册到容器
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
factory.registerBeanDefinition("car1", car1);
factory.registerBeanDefinition("car2", car2);
factory.registerBeanDefinition("compositeObj", compositeObj);
//下面我们将容器中所有的bean输出
for (String beanName : factory.getBeanDefinitionNames()) {
System.out.println(String.format("%s->%s", beanName, factory.getBean(beanName)));
}
}2、Bean元信息解析阶段
xml文件定义bean的解析。
properties文件定义bean的解析。
注解方式定义bean的解析。
XML方式解析:XmlBeanDefinitionReader
案例
<?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-4.3.xsd"> <bean id="car" class="com.javacode2018.lesson002.demo1.Car"> <property name="name" value="奥迪"/> </bean> <bean id="car1" class="com.javacode2018.lesson002.demo1.Car"> <property name="name" value="保时捷"/> </bean> <bean id="car2" parent="car1"/> <bean id="user" class="com.javacode2018.lesson002.demo1.User"> <property name="name" value="路人甲Java"/> <property name="car" ref="car1"/> </bean> </beans>
将bean xml解析为BeanDefinition对象
/**
* xml方式bean配置信息解析
*/
@Test
public void test1() {
// 定义一个spring容器,这个容器默认实现了BeanDefinitionRegistry,所以本身就是一个bean注册器
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
// 定义一个xml的BeanDefinition读取器,需要传递一个BeanDefinitionRegistry(bean注册器)对象
XmlBeanDefinitionReader xmlBeanDefinitionReader = new XmlBeanDefinitionReader(factory);
// 指定bean xml配置文件的位置
String location = "classpath:/com/javacode2018/lesson002/demo2/beans.xml";
// 通过XmlBeanDefinitionReader加载bean xml文件,然后将解析产生的BeanDefinition注册到容器容器中
int countBean = xmlBeanDefinitionReader.loadBeanDefinitions(location);
System.out.println(String.format("共注册了 %s 个bean", countBean));
// 打印出注册的bean的配置信息
for (String beanName : factory.getBeanDefinitionNames()) {
// 通过名称从容器中获取对应的BeanDefinition信息
BeanDefinition beanDefinition = factory.getBeanDefinition(beanName);
// 获取BeanDefinition具体使用的是哪个类
String beanDefinitionClassName = beanDefinition.getClass().getName();
// 通过名称获取bean对象
Object bean = factory.getBean(beanName);
// 打印输出
System.out.println(beanName + ":");
System.out.println(" beanDefinitionClassName:" + beanDefinitionClassName);
System.out.println(" beanDefinition:" + beanDefinition);
System.out.println(" bean:" + bean);
}
}properties文件定义bean的解析:PropertiesBeanDefinitionReader
car.(class)=com.javacode2018.lesson002.demo1.Car car.name=奥迪 car1.(class)=com.javacode2018.lesson002.demo1.Car car1.name=保时捷 car2.(parent)=car1 user.(class)=com.javacode2018.lesson002.demo1.User user.name=路人甲Java user.car(ref)=car
将bean properties文件解析为BeanDefinition对象
/**
* properties文件方式bean配置信息解析
*/
@Test
public void test2() {
// 定义一个spring容器,这个容器默认实现了BeanDefinitionRegistry,所以本身就是一个bean注册器
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
// 定义一个properties的BeanDefinition读取器,需要传递一个BeanDefinitionRegistry(bean注册器)对象
PropertiesBeanDefinitionReader propertiesBeanDefinitionReader = new
PropertiesBeanDefinitionReader(factory);
// 指定bean xml配置文件的位置
String location ="classpath:/com/javacode2018/lesson002/demo2/beans.properties";
// 通过PropertiesBeanDefinitionReader加载bean properties文件,然后将解析产生的BeanDefinition注册到容器容器中
int countBean = propertiesBeanDefinitionReader.loadBeanDefinitions(location);
System.out.println(String.format("共注册了 %s 个bean", countBean));
// 打印出注册的bean的配置信息
for (String beanName : factory.getBeanDefinitionNames()) {
// 通过名称从容器中获取对应的BeanDefinition信息
BeanDefinition beanDefinition = factory.getBeanDefinition(beanName);
// 获取BeanDefinition具体使用的是哪个类
String beanDefinitionClassName = beanDefinition.getClass().getName();
// 通过名称获取bean对象
Object bean = factory.getBean(beanName);
// 打印输出
System.out.println(beanName + ":");
System.out.println(" beanDefinitionClassName:" +
beanDefinitionClassName);
System.out.println(" beanDefinition:" + beanDefinition);
System.out.println(" bean:" + bean);
}
}注解方式:PropertiesBeanDefinitionReader
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
@Primary
@Lazy
public class Service1 {
@Override
public String toString() {
return ToStringBuilder.reflectionToString(this, ToStringStyle.MULTI_LINE_STYLE);
}
}
public class Service2 {
@Autowired
private Service1 service1;
@Override
public String toString() {
return ToStringBuilder.reflectionToString(this, ToStringStyle.MULTI_LINE_STYLE);
}
}注解定义的bean解析为BeanDefinition,如下:
@Test
public void test3() {
// 定义一个spring容器,这个容器默认实现了BeanDefinitionRegistry,所以本身就是一个bean注册器
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
// 定义一个注解方式的BeanDefinition读取器,需要传递一个BeanDefinitionRegistry(bean注册器)对象
AnnotatedBeanDefinitionReader annotatedBeanDefinitionReader = new AnnotatedBeanDefinitionReader(factory);
// 通过PropertiesBeanDefinitionReader加载bean properties文件,然后将解析产生的BeanDefinition注册到容器容器中
annotatedBeanDefinitionReader.register(Service1.class, Service2.class);
// 打印出注册的bean的配置信息
for (String beanName : new String[]{"service1", "service2"}) {
// 通过名称从容器中获取对应的BeanDefinition信息
BeanDefinition beanDefinition = factory.getBeanDefinition(beanName);
// 获取BeanDefinition具体使用的是哪个类
String beanDefinitionClassName = beanDefinition.getClass().getName();
// 通过名称获取bean对象
Object bean = factory.getBean(beanName);
// 打印输出
System.out.println(beanName + ":");
System.out.println(" beanDefinitionClassName:" +
beanDefinitionClassName);
System.out.println(" beanDefinition:" + beanDefinition);
System.out.println(" bean:" + bean);
}
}运行输出
factory.getBeansOfType(BeanPostProcessor.class).values().forEach(factory::addBeanPostProcessor);
3、Spring Bean注册阶段
Bean注册接口:BeanDefinitionRegistry
public interface BeanDefinitionRegistry extends AliasRegistry {
/**
* 注册一个新的bean定义
* beanName:bean的名称
* beanDefinition:bean定义信息
*/
void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws BeanDefinitionStoreException;
/**
* 通过bean名称移除已注册的bean
* beanName:bean名称
*/
void removeBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;
/**
* 通过名称获取bean的定义信息
* beanName:bean名称
*/
BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;
/**
* 查看beanName是否注册过
*/
boolean containsBeanDefinition(String beanName);
/**
* 获取已经定义(注册)的bean名称列表
*/
String[] getBeanDefinitionNames();
/**
* 返回注册器中已注册的bean数量
*/
int getBeanDefinitionCount();
/**
* 确定给定的bean名称或者别名是否已在此注册表中使用
* beanName:可以是bean名称或者bean的别名
*/
boolean isBeanNameInUse(String beanName);
}别名注册接口:AliasRegistry
BeanDefinitionRegistry 接口继承了 AliasRegistry 接口,这个接口中定义了操作bean别名的一些方法,看一下其源码:
public interface AliasRegistry {
/**
* 给name指定别名alias
*/
void registerAlias(String name, String alias);
/**
* 从此注册表中删除指定的别名
*/
void removeAlias(String alias);
/**
* 判断name是否作为别名已经被使用了
*/
boolean isAlias(String name);
/**
* 返回name对应的所有别名
*/
String[] getAliases(String name);
}BeanDefinitionRegistry唯一实现:DefaultListableBeanFactory
4、BeanDefinition合并阶段
5、Bean Class加载阶段
private volatile Object beanClass;
6、Bean实例化阶段
Bean实例化前操作。
Bean实例化操作。
Bean实例化前操作
private final List<BeanPostProcessor> beanPostProcessors = new CopyOnWriteArrayList<>();
@Nullable
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
if (result != null) {
return result;
}
}
}
return null;
}default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
return null;
}Bean实例化操作
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
Constructor<?>[] ctors = ibp.determineCandidateConstructors(beanClass, beanName);
if (ctors != null) {
return ctors;
}
}
}会调用 SmartInstantiationAwareBeanPostProcessor#determineCandidateConstructors 方法,这个方法会返回候选的构造器列表,也可以返回空,看一下这个方法的源码:
@Nullable
default Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, String beanName) throws BeansException {
return null;
}案例
@Target(ElementType.CONSTRUCTOR)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface MyAutowried {
}public class Person {
private String name;
private Integer age;
public Person() {
System.out.println("调用 Person()");
}
@MyAutowried
public Person(String name) {
System.out.println("调用 Person(String name)");
this.name = name;
}
public Person(String name, Integer age) {
System.out.println("调用 Person(String name, int age)");
this.name = name;
this.age = age;
}
//省略get set toString方法
}自定义一个SmartInstantiationAwareBeanPostProcessor。代码的逻辑:将 @MyAutowried 标注的构造器列表返回
public class MySmartInstantiationAwareBeanPostProcessor implements SmartInstantiationAwareBeanPostProcessor {
@Override
public Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, String beanName) throws BeansException {
System.out.println(beanClass);
System.out.println("调用 MySmartInstantiationAwareBeanPostProcessor.determineCandidateConstructors 方法");
Constructor<?>[] declaredConstructors = beanClass.getDeclaredConstructors();
//获取有@MyAutowried注解的构造器列表
List<Constructor<?>> collect = Arrays.stream(declaredConstructors).filter(
constructor -> constructor.isAnnotationPresent(MyAutowried.class)).collect(Collectors.toList());
Constructor[] constructors = collect.toArray(new Constructor[collect.size()]);
return constructors.length != 0 ? constructors : null;
}
}测试
@Test
public void test2() {
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
//创建一个SmartInstantiationAwareBeanPostProcessor,将其添加到容器中
factory.addBeanPostProcessor(new MySmartInstantiationAwareBeanPostProcessor());
factory.registerBeanDefinition("name",
BeanDefinitionBuilder.
genericBeanDefinition(String.class).
addConstructorArgValue("Java").
getBeanDefinition());
factory.registerBeanDefinition("person",
BeanDefinitionBuilder.
genericBeanDefinition(Person.class).
getBeanDefinition());
Person person = factory.getBean("person", Person.class);
System.out.println(person);
}7、BeanDefinition的后置处理
protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd,Class<?> beanType, String beanName) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof MergedBeanDefinitionPostProcessor) {
MergedBeanDefinitionPostProcessor bdp = (MergedBeanDefinitionPostProcessor) bp;
bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName);
}
}
}会调用 MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition 方法,看一下这个方法的源码:
void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName)
// 在 postProcessMergedBeanDefinition 方法中对 @Autowired、@Value 标注的方法、字段进行缓存 org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor // 在 postProcessMergedBeanDefinition 方法中对 @Resource 标注的字段、@Resource 标注的方法、 @PostConstruct 标注的字段、 @PreDestroy标注的方法进行缓存 org.springframework.context.annotation.CommonAnnotationBeanPostProcessor
8、Bean属性设置阶段
实例化后阶段。
Bean属性赋值前处理。
Bean属性赋值。
实例化后阶段
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
return;
}
}
}postProcessAfterInstantiation 方法返回false的时候,后续的Bean属性赋值前处理、Bean属性赋值都会被跳过了。
default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
return true;
}Bean属性赋值前阶段
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
if (filteredPds == null) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
return;
}
}
pvs = pvsToUse;
}
}来看一下 postProcessProperties 这个方法的定义:
@Nullable
default PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
return null;
}AutowiredAnnotationBeanPostProcessor:在这个方法中对@Autowired、@Value标注的字段、方法注入值。
CommonAnnotationBeanPostProcessor:在这个方法中对@Resource标注的字段和方法注入值。
Bean属性赋值阶段
9、Bean初始化阶段
Bean Aware接口回调。
Bean初始化前操作。
Bean初始化操作。
Bean初始化后操作。
Bean Aware接口回调
private void invokeAwareMethods(final String beanName, final Object bean) {
if (bean instanceof Aware) {
if (bean instanceof BeanNameAware) {
((BeanNameAware) bean).setBeanName(beanName);
}
if (bean instanceof BeanClassLoaderAware) {
ClassLoader bcl = getBeanClassLoader();
if (bcl != null) {
((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
}
}
if (bean instanceof BeanFactoryAware) {
((BeanFactoryAware)bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
}
}
}BeanNameAware:将bean的名称注入进去。
BeanClassLoaderAware:将BeanClassLoader注入进去。
BeanFactoryAware:将BeanFactory注入进去。
Bean初始化前操作
@Override
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName) throws BeansException {
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor.postProcessBeforeInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}org.springframework.context.support.ApplicationContextAwareProcessor org.springframework.context.annotation.CommonAnnotationBeanPostProcess
ApplicationContextAwareProcessor注入6个Aware接口对象
EnvironmentAware:注入Environment对象。
EmbeddedValueResolverAware:注入EmbeddedValueResolver对象。
ResourceLoaderAware:注入ResourceLoader对象。
ApplicationEventPublisherAware:注入ApplicationEventPublisher对象。
MessageSourceAware:注入MessageSource对象。
ApplicationContextAware:注入ApplicationContext对象。
CommonAnnotationBeanPostProcessor调用@PostConstruct标注的方法
@PostConstruct
public void postConstruct1() {
System.out.println("postConstruct1()");
}@Test
public void test6() {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
context.register(Person.class);
context.refresh();
}Bean初始化阶段
调用InitializingBean接口的afterPropertiesSet方法。
调用定义bean的时候指定的初始化方法。
调用InitializingBean接口的afterPropertiesSet方法
public interface InitializingBean {
void afterPropertiesSet() throws Exception;
}调用bean定义的时候指定的初始化方法
<bean init-method="bean中方法名称"/>
方式2:@Bean的方式指定初始化方法
@Bean(initMethod = "初始化的方法")
方式3:api的方式指定初始化方法
this.beanDefinition.setInitMethodName(methodName);
初始化方法最终会赋值给下面这个字段
org.springframework.beans.factory.support.AbstractBeanDefinition#initMethodName
Bean初始化后阶段
@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException {
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor.postProcessAfterInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}10、所有单例bean初始化完成后阶段
public interface SmartInitializingSingleton {
void afterSingletonsInstantiated();
}调用逻辑在下面这个方法中
/** * 确保所有非lazy的单例都被实例化,同时考虑到FactoryBeans。如果需要,通常在工厂设置结束时调用。 */ org.springframework.beans.factory.support.DefaultListableBeanFactory#preInstantiateSingletons
例子
@Component
public class Service1 {
public Service1() {
System.out.println("create " + this.getClass());
}
}
@Component
public class Service2 {
public Service2() {
System.out.println("create " + this.getClass());
}
}
@Component
public class MySmartInitializingSingleton implements SmartInitializingSingleton {
@Override
public void afterSingletonsInstantiated() {
System.out.println("所有bean初始化完毕!");
}
}
@Test
public void test1() {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
context.register(DemoTest.class);
System.out.println("开始启动容器!");
context.refresh();
System.out.println("容器启动完毕!");
}开始启动容器! create class com.Service1 create class com.Service2 所有bean初始化完毕! 容器启动完毕!
通过api的方式让DefaultListableBeanFactory去回调SmartInitializingSingleton。
@Test
public void test2() {
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
factory.registerBeanDefinition("service1", BeanDefinitionBuilder.genericBeanDefinition(Service1.class).getBeanDefinition());
factory.registerBeanDefinition("service2", BeanDefinitionBuilder.genericBeanDefinition(Service2.class).getBeanDefinition());
factory.registerBeanDefinition("mySmartInitializingSingleton",
BeanDefinitionBuilder.genericBeanDefinition(MySmartInitializingSingleton.class). getBeanDefinition());
System.out.println("准备触发所有单例bean初始化");
// 触发所有bean初始化,并且回调SmartInitializingSingleton#afterSingletonsInstantiated 方法
factory.preInstantiateSingletons();
}11、Bean使用
12、Bean销毁阶段
触发bean销毁的几种方式
调用org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#destroyBean
调用org.springframework.beans.factory.config.ConfigurableBeanFactory#destroySingletons
调用ApplicationContext中的close方法
Bean销毁阶段会依次执行
轮询beanPostProcessors列表,如果是DestructionAwareBeanPostProcessor这种类型的,会调用其内部的postProcessBeforeDestruction()方法。
如果bean实现了org.springframework.beans.factory.DisposableBean接口,会调用这个接口中的destroy()方法。
调用bean自定义的销毁方法。
DestructionAwareBeanPostProcessor接口
public interface DestructionAwareBeanPostProcessor extends BeanPostProcessor {
/**
* bean销毁前调用的方法
*/
void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException;
/**
* 用来判断bean是否需要触发postProcessBeforeDestruction方法
*/
default boolean requiresDestruction(Object bean) {
return true;
}
}自定义销毁方法有3种方式
<bean destroy-method="bean中方法名称"/>
方式2:@Bean中指定销毁方法
@Bean(destroyMethod = "初始化的方法")
方式3:api的方式指定销毁方法
this.beanDefinition.setDestroyMethodName(methodName);
初始化方法最终会赋值给下面这个字段
org.springframework.beans.factory.support.AbstractBeanDefinition#destroyMethodName
自定义DestructionAwareBeanPostProcessor
public class MyDestructionAwareBeanPostProcessor implements DestructionAwareBeanPostProcessor {
@Override
public void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException {
System.out.println("准备销毁bean:" + beanName);
}
}触发@PreDestroy标注的方法被调用
public class ServiceB {
public ServiceB() {
System.out.println("create " + this.getClass());
}
@PreDestroy
public void preDestroy() {
System.out.println("preDestroy()");
}
}@Test
public void test2() {
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
//添加自定义的DestructionAwareBeanPostProcessor
factory.addBeanPostProcessor(new MyDestructionAwareBeanPostProcessor());
//将CommonAnnotationBeanPostProcessor加入,这个会处理bean中标注@PreDestroy注解的方法
factory.addBeanPostProcessor(new CommonAnnotationBeanPostProcessor());
//向容器中注入bean
factory.registerBeanDefinition("serviceB", BeanDefinitionBuilder.genericBeanDefinition(ServiceB.class).getBeanDefinition());
//触发所有单例bean初始化
factory.preInstantiateSingletons();
System.out.println("销毁serviceB");
//销毁指定的bean
factory.destroySingleton("serviceB");
}销毁方法调用的顺序
@PreDestroy标注的所有方法。
DisposableBean接口中的destroy()。
自定义的销毁方法。
AbstractApplicationContext类(非常重要的类)
BeanFactory接口
DefaultListableBeanFactory类
其他3个类
AbstractApplicationContext类
public abstract ConfigurableListableBeanFactory getBeanFactory() throws IllegalStateException; protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory)
第一个方法:getBeanFactory()
第二个方法:registerBeanPostProcessors
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>(); List<BeanPostProcessor> orderedPostProcessors; List<BeanPostProcessor> nonOrderedPostProcessors; List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
先说一下:当到方法的时候,Spring容器中已经完成了所有Bean的注册。
priorityOrderedPostProcessors(指定优先级的BeanPostProcessor)
orderedPostProcessors(指定了顺序的BeanPostProcessor)
nonOrderedPostProcessors(未指定顺序的BeanPostProcessor)
internalPostProcessors
Bean元信息配置阶段:获取Bean元信息,Bean原信息定义方式(API的方式、xml方式、properties文件的方式、注解方式)。
Bean元信息解析阶段:利用Bean元信息,生成BeanDefinition。
Spring Bean注册阶段:利用生成BeanDefinition去注册Bean。
BeanDefinition合并阶段:合并具有父子关系bean。最终得到一个RootBeanDefinition。
Bean Class加载阶段:这个阶段就是将bean的class名称转换为Class类型的对象。
Bean实例化阶段:
Bean实例化前操作:会调用InstantiationAwareBeanPostProcessor#postProcessBeforeInitialization()方法,我们可以利用这个方法跳过Spring自带的实例化bean过程。
实例化操作:会调用SmartInstantiationAwareBeanPostProcessor#determineCandidateConstructors()方法逻辑,如何实例化(Supplier\工厂方法创建对象\推断构造方法)。
BeanDefinition的后置处理:调用MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition()方法。
Bean属性设置阶段:
Bean实例化后:会调用InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation()方法,方法返回false则跳过属性赋值。
Bean属性赋值前:会调用InstantiationAwareBeanPostProcessor#postProcessProperties()方法。
Bean属性赋值:循环处理PropertyValues中的属性值信息,通过反射调用set方法将属性的值设置到bean实例中。
Bean初始化阶段:
Bean Aware接口回调:如果Bean实现了BeanNameAware、 BeanClassLoaderAware、 BeanFactoryAware、EnvironmentAware、EmbeddedValueResolverAware、ResourceLoaderAware、ApplicationEventPublisherAware、MessageSourceAware、ApplicationContextAware。会依次调用相应实现的接口方法。
Bean初始化前:会调用BeanPostProcessor#postProcessBeforeInitialization()方法。
Bean初始化:
调用InitializingBean#afterPropertiesSet()方法。
调用定义bean的时候指定的初始化方法。
Bean初始化后:调用BeanPostProcessor#postProcessAfterInitialization()方法。
所有单例bean初始化完成后阶段:所有单例bean实例化完成之后,Spring会回调SmartInitializingSingleton#afterSingletonsInstantiated()方法。
Bean使用阶段。
Bean销毁阶段:
轮询beanPostProcessors列表,如果是DestructionAwareBeanPostProcessor这种类型的,会调用其内部的postProcessBeforeDestruction()方法。
如果bean实现了org.springframework.beans.factory.DisposableBean接口,会调用这个接口中的destroy()方法。
调用bean自定义的销毁方法。
Bean生命周期流程图
参考:路人甲-Spring系列
版权声明
非特殊说明,本文由Zender原创或收集发布,欢迎转载。
ZENDER










发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。