一、BeanDefinition
什么是BeanDefinition,从英文的名字中我们就可以知道它是用来定义Bean的
bean的创建是根据我们提供的一些配置的元数据,比如xml。在容器里,这些由我们配置的元数据被表示为BeanDefinition
二、bean的生命周期概述
1.实例化bean(createBeanInstance)
该阶段主要是实例化出一个bean对象,主要通过反射以及cglib动态字节码生成对象(可以理解为new了一个对象出来了)
2.属性赋值(populateBean)
该阶段主要是用于给bean对象的属性赋值(比如设置了@Autowired的属性赋值)
思考:Spring如何解决循环依赖
3.bean的初始化(initializeBean)
调用org.springframework.beans.factory.InitializingBean接口的afterPropertiesSet() 以及调用我们指定的init-method(例如xml的init-method、@Bean的init参数)
思考:@PostConstruct是在这个阶段完成的吗
以上的三个阶段,是Bean创建的三个阶段,对应代码里的这三个部分
4.使用中
bean的使用阶段,也是业务调用的阶段
5.销毁
调用destroy的方法
6.Bean生命周期(创建)的泳道图:
三、bean的创建——实例化bean(InstanceBean)
从代码看,我们知道InstanceBean分为几种实例化方式
1.通过factoryBean实例化(红框1)
是否使用BeanDefinition里面的factoryMethod实例化(@Bean注解是使用工厂方法实例化的,实例化的方式可以自定义)
2.通过带参构造器实例化(红框2)
使用autowireConstructor方法构建(会递归实例化构造器入参的bean)
3.通过无参构造器实例化(红框3)
对于创建bean的方式2和方式3,最终都是通过反射或者cglib字节码实例化对象
四、bean的创建——属性赋值(PopulateBean)
可以看到,我分别框了四个红框,这四个红框分别是这个PopulateBean的主要的两个步骤
1.InstantiationAwareBeanPostProcessor的实例化后置处理(postProcessBeforeInstantiation)。(红框1)
由于这部分是实例化的后置处理,这里我们讲的是属性赋值,我们先暂时忽略这部分代码
2.属性自动装配初始化。(红框2)
这部分是获取BeanDefinition里面的resolvedAutowireMode(自动装配模式)。然后根据自动装配的模式(根据属性类型装配AUTOWIRE_BY_TYPE或者根据属性名装配AUTOWIRE_BY_NAME)查找bean中的set方法,然后匹配对应的属性,查找或递归创建出对应的bean,放到pvs(PropertyValues)里面。
1.AutowireMode自动装配模式的配置在@Bean的注解的autowire属性,xml的autowire属性写入
2.除了@Bean的注解的autowire属性,xml的autowire属性写入,还以通过修改BeanDefinition,典型使用——MyBatis,definition.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_TYPE)
3.如果不设置,都是默认AUTOWIRE_NO,即不进行属性的自动装配
4.可以看到我的描述,这部分代码并没有将属性赋值给bean,只是获取到后放pvs(PropertyValues)里面,赋值的操作是第四个红框
5.AutowireMode和注解@Autowire没有任何关系
3.InstantiationAwareBeanPostProcessor的属性值处理(postProcessPropertyValues)。(红框3)
这部分代码是@Autowire等注解注入的主要地方
InstantiationAwareBeanPostProcessor有多个实现类,代码中遍历了多个实现类去装配属性。
例如:
- AutowiredAnnotationBeanPostProcessor实现装配@Autowired、@Inject和@Value
- CommonAnnotationBeanPostProcessor实现装配@Resource、@WebServiceRef、@EJB
- ……
4.属性自动装配赋值(红框4)
将红框2中拿到的属性赋值到当前的bean即applyPropertyValues部分的代码
5.总结
总结:PopulateBean的逻辑其实主要就两个
一个是通过自动装配的模式对set方法对应的属性进行装配,主要有三种
- AUTOWIRE_NO(默认,不进行属性自动装配)
- AUTOWIRE_BY_NAME(通过属性名进行自动装配)
- AUTOWIRE_BY_TYPE(通过属性类型进行自动装配)
另外一个是通过循环调用InstantiationAwareBeanPostProcessor#postProcessPropertyValues方法对属性进行注入,@Autowired、@Resource、@Value等注解都是在这里进行属性注入的
五、bean的创建——bean的初始化(InitializeBean)
代码这里我圈了四个红框,我们只需要关注第三个红框就行
- 红框1是判断是否是BeanNameAware、BeanClassLoaderAware和BeanFactoryAware接口,如果是,则要分别注入beanName、classLoader和beanFactory,这里我们先忽略
- 红框2是调用BeanPostProcessor#postProcessBeforeInitialization执行初始化的前置操作,这里我们先忽略
- 红框3是初始化的主代码,执行初始化方法invokeInitMethods
- 红框4是调用BeanPostProcessor#postProcessAfterInitialization执行初始化的后置操作,这里我们先忽略
接下来我们来看一下初始化的主方法invokeInitMethods里面主要是干了什么
1.遍历执行InitializingBean#afterPropertiesSet方法
使用场景:策略模式+afterPropertiesSet
2.执行bean执行的初始化方法(init-method)
bean的初始化方法的指定通常可以通过注解org.springframework.context.annotation.Bean#initMethod或者xml的init-method的属性来指定。具体实现的逻辑是通过反射来调用改方法
六、bean创建的三个阶段的总结
- InstanceBean
- 通过factoryBean实例化
- 通过带参构造器实例化
- 通过无参构造器实例化
- PopulateBean
- AutowireMode
- AUTOWIRE_NO(默认,不进行属性自动装配)
- AUTOWIRE_BY_NAME(通过属性名进行自动装配)
- AUTOWIRE_BY_TYPE(通过属性类型进行自动装配)
- InstantiationAwareBeanPostProcessor#postProcessPropertyValues对@Autowired、@Resource、@Value等注解进行属性赋值
- AutowireMode
- InitializeBean
- 执行InitializingBean#afterPropertiesSet方法
- 执行init-method(@Bean#initMethod和xml的init-method)
七、bean生命周期的扩展点
我们将开展点分成两类
- Bean的生命周期成员InitializingBean、DisposableBean
- Bean的生命周期的重要参与者InstantiationAwareBeanPostProcessor、BeanPostProcessor
1.InitializingBean/DisposableBean接口
InitializingBean接口对应bean初始化,DisposableBean对应bean的销毁,这两个接口类似,我们只挑InitializingBean进行讲解
InitializingBean接口只有一个方法afterPropertiesSet,bean对应的类实现了这个接口就能是在bean初始化阶段处理一些事情。
2.BeanPostProcessor接口
BeanPostProcessor接口影响到了bean的初始化阶段
它一共有两个接口
- BeanPostProcessor#postProcessBeforeInitialization
- BeanPostProcessor#postProcessAfterInitialization
顾名思义,一个是初始化阶段前调用,一个是初始化阶段后调用,调用处详见五、bean的创建——bean的初始化(InitializeBean)的红框2和红框4
BeanPostProcessor#postProcessAfterInitialization的典型使用AOP、@PostConstruct
3.InstantiationAwareBeanPostProcessor接口
InstantiationAwareBeanPostProcessor接口参与到了Bean的实例化、属性赋值、以及初始化阶段
它一共有五个接口
- InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation
bean实例化(InstanceBean)前调用,是整个创建bean的前置逻辑,在这里可以自己创建bean,创建完之后就直接返回了,不走Spring创建bean的逻辑
- InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation
bean实例化(InstanceBean)后调用,属性赋值(PopulateBean)前调用,调用处详见四、bean的创建——属性赋值(PopulateBean)的红框1
- InstantiationAwareBeanPostProcessor#postProcessPropertyValues
属性赋值(PopulateBean)的主逻辑之一,CommonAnnotationBeanPostProcessor实现了这个方法对@Resource的属性赋值,AutowiredAnnotationBeanPostProcessor实现了这个方法对@Value、@Autowired的属性赋值,调用处详见四、bean的创建——属性赋值(PopulateBean)的红框3
- BeanPostProcessor#postProcessBeforeInitialization
同BeanPostProcessor
- BeanPostProcessor#postProcessAfterInitialization
同BeanPostProcessor
八、各式各样的为Aware接口
Aware接口主要分成两类
1.BeanNameAware、BeanClassLoaderAware和BeanFactoryAware接口
这三个接口在BeanPostProcessor#postProcessBeforeInitialization之前执行,这几个接口不参与到bean的创建中,只是用来获取某些东西,调用处详见五、bean的创建——bean的初始化(InitializeBean)的红框1
2.其他的Aware接口
这些接口也都不参与到Bean的创建中,也是用来获取某些东西,通过BeanPostProcessor#postProcessBeforeInitialization注入到Bean中
class ApplicationContextAwareProcessor implements BeanPostProcessor {
private final ConfigurableApplicationContext applicationContext;
@Override
public Object postProcessBeforeInitialization(final Object bean, String beanName) throws BeansException {
invokeAwareInterfaces(bean);
return bean;
}
private void invokeAwareInterfaces(Object bean) {
if (bean instanceof Aware) {
if (bean instanceof EnvironmentAware) {
((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());
}
if (bean instanceof EmbeddedValueResolverAware) {
((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(this.embeddedValueResolver);
}
if (bean instanceof ResourceLoaderAware) {
((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);
}
if (bean instanceof ApplicationEventPublisherAware) {
((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext);
}
if (bean instanceof MessageSourceAware) {
((MessageSourceAware) bean).setMessageSource(this.applicationContext);
}
if (bean instanceof ApplicationContextAware) {
((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
}
}
}
}
复制代码
- EnvironmentAware获取Spring配置文件
- EmbeddedValueResolverAware获取Spl解析器
- ApplicationContextAware(ResourceLoaderAware\ApplicationEventPublisherAware\MessageSourceAware)获取bean对象
- ……
九、总结
- 创建的三个阶段
- bean的实例化
- 通过factoryBean实例化
- 带参构造器实例化
- 无参构造器实例化
- bean的属性赋值
- 设置AutowireMode赋值
- 实现InstantiationAwareBeanPostProcessor#postProcessPropertyValues接口赋值
- bean的初始化
- 运行的init-method方法
- 运行InitializingBean#afterPropertiesSet接口
- bean的实例化
- 两个生命周期接口
- InitializingBean#afterPropertiesSet(属于bean的初始化阶段)
- DisposableBean#destroy(属于bean的销毁阶段)
- 两个生命周期参与接口
- BeanPostProcessor
- postProcessBeforeInitialization(bean初始化阶段前置调用)
- postProcessAfterInitialization(bean初始化后置调用)
- InstantiationAwareBeanPostProcessor
- postProcessAfterInstantiation(bean实例化阶段前置调用)
- postProcessBeforeInstantiation(bean实例化阶段的后置调用)
- postProcessPropertyValues(bean的属性赋值中的一种)
- postProcessBeforeInitialization(bean的初始化阶段的前置调用)
- postProcessAfterInitialization(bean的初始化阶段的后置调用)
- BeanPostProcessor
- 各种各种各样的Aware接口
- BeanNameAware、BeanClassLoaderAware和BeanFactoryAware接口
- ApplicationContextAwareProcessor注入的Aware