准备
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,使用构造器或者工厂方法实例化beanpopulateBean,对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() { |