准备
pom
依赖,jdk
版本为1.8
1 |
|
为了方便分析Spring
中bean
的生命周期,我们使用@Lazy
来注解bean
1 |
|
我们使用测试程序来分析person
的加载过程
1 | public static void main(String[] args) { |
分析
doGetBean
因为使用了@Lazy
,所以Person
在执行context.getBean(Person.class)
时才加载,我们debug
进去大致了解一下关键的加载过程
1 | //交由BeanFactory去加载 |
省略中间过程,最终会调用BeanFactory
的doGetBean
方法
1 | public <T> T getBean(String name, @Nullable Class<T> requiredType, @Nullable Object... args) |
doGetBean
大致流程如下:
- 如果是单例模式的,则尝试从缓存中获取
bean
- 尝试从父类
BeanFactory
中加载bean
- 加载依赖
bean
,@DependsOn
注解的bean
- 使用方法
createBean(beanName, mbd, args)
,加载单例 bean
doGetBean
源码,无视其他代码,只关心我们需要了解的
1 | protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType, |
createBean
createBean
大致流程如下:
createBeanInstance
,使用构造器或者工厂方法实例化bean
populateBean
,对bean
进行数据的初始化操作,比如加载@autowire
的bean
,@value
的属性赋值,@PostConstruct
方法执行等initializeBean
,执行BeanDefinition
中定义的initMethod
,一般在xml
配置中(<bean class="Person" init-method="initMethod"/>
),或者@Bean(initMethod = "initMethod")
中定义的方法名
createBean
源码,无视其他代码,只关心我们需要了解的
1 | protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args) |
populateBean
这里我们简单介绍一下@Autowired
是何时被加载的。我们通过打断点,并设置evaluate
语句,在断点处输出日志的方式查看
断点调试最后输出的日志如下
我们可以得知被@Autowired
的属性或方法是否处理器AutowiredAnnotationBeanPostProcessor
去实现的,具体加载过程参考
1 | protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) { |
initializeBean
initializeBean
大致执行步骤如下:
- 若接口实现了
Aware
,则执行对应的方法 - 执行所有
BeanPostProcessor
的postProcessBeforeInitialization
方法 - 执行
BeanDefinition
中定义的init-method
- 执行所有
BeanPostProcessor
的postProcessAfterInitialization
方法
1 | protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) { |
我们对上述initializeBean
的第三步骤不做过多介绍,其大致执行过程为在初始化BeanDefinition
时,将initMethod
的值通过下述方法加载
1 | void setInitMethodName(@Nullable String initMethodName); |
然后initializeBean
通过invokeInitMethods
来执行initMethod
applyBeanPostProcessorsBeforeInitialization
我们同样通过断点调试的方式来观察,@PostConstruct
方法是何时被执行的
我们可以得知是在CommonAnnotationBeanPostProcessor
中被处理的
我们查看其源码
1 |
|
查看findLifecycleMetadata
-->buildLifecycleMetadata
细节
我们只需要了解this.initAnnotationType
, this.destroyAnnotationType
的赋值情况即可
1 | private LifecycleMetadata buildLifecycleMetadata(final Class<?> clazz) { |
我们通过查看CommonAnnotationBeanPostProcessor
的构造器发现了@PostConstruct
的赋值过程。
1 | public CommonAnnotationBeanPostProcessor() { |