1、生命周期概括图
首先说一下Servlet的生命周期:实例化,初始init,接收请求service,销毁destroy。Spring中Bean的生命周期也类似,可以用下图概括:
现在我们就根据上面的步骤来分析一下每一步的实际实现是怎样的。(以下基于spring-boot Version 2.7.6
分析)
2、源码分析
我们创建一个示例代码,从而方便进入查看源码。自定义一个Bean
和BeanPostProcessor
:
class MyBean implements ApplicationContextAware, BeanNameAware {
private MyBeanPostProcessor myBeanPostProcessor;
public MyBean(){
System.out.println("创建了一个myBean,构造器注入");
}
@Autowired
public void setMyPostProcessor(MyBeanPostProcessor myBeanPostProcessor){
System.out.println("Setter注入");
this.myBeanPostProcessor = myBeanPostProcessor;
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
System.out.println("执行ApplicationContextAware接口,实际用ApplicationContextBeanPostProcessor执行");
}
@Override
public void setBeanName(String name) {
System.out.println("执行BeanNameAware,name为:" + name);
}
@PostConstruct
public void init(){
System.out.println("初始化Bean");
}
@PreDestroy
public void destroy(){
System.out.println("销毁Bean");
}
}
class MyBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("初始化前" + beanName);
return BeanPostProcessor.super.postProcessBeforeInitialization(bean, beanName);
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("初始化后" + beanName);
return BeanPostProcessor.super.postProcessAfterInitialization(bean, beanName);
}
}
再创建一个测试类:
class MySpringboot001ApplicationTests {
@Test
void contextLoads() {
// Spring容器创建
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
// 注册配置类(创建BeanDefinition)
applicationContext.register(MyBeanPostProcessor.class);
applicationContext.register(MyBean.class);
// 加载刷新配置(这一步才会创建Bean)
applicationContext.refresh();
}
}
2.1 Spring容器创建
如代码所示,我们手动创建了一个Spring容器AnnotationConfigApplicationContext
。AnnotationConfigApplicationContext
是 Spring 框架提供的一个用于基于注解的配置方式创建和管理 Spring Bean的高级容器。以下是创建容器的源码:
2.2 扫描或者注册配置类
我们往容器中注册两个Bean,进入register
方法:
2.3 生成BeanDefinition
接着一直到org.springframework.context.annotation.AnnotatedBeanDefinitionReader#doRegisterBean
:
进入org.springframework.beans.factory.support.BeanDefinitionReaderUtils#registerBeanDefinition
:
进入org.springframework.context.support.GenericApplicationContext#registerBeanDefinition
:
2.4 把BeanDefinition放进beanDefinitionMap<beanName, BeanDefinition>中
最后进入org.springframework.beans.factory.support.DefaultListableBeanFactory#registerBeanDefinition
:
BeanDefinition
是 Spring 框架中的一个概念,用于描述和定义一个 bean 的元数据信息。每个被 Spring 管理的 bean 都对应着一个 BeanDefinition 对象。
BeanDefinition 中主要包含了以下关键信息:
-
Class:表示该 bean 的类。
-
Scope:表示该 bean 的作用域(例如单例、原型等)。
-
构造函数参数和属性值:表示构造函数参数和属性的值。
-
依赖关系:表示该 bean 依赖的其他 bean 的名称或类型。
-
生命周期回调方法:表示该 bean 的初始化方法和销毁方法。
-
懒加载:表示该 bean 是否延迟加载。
到这里结束,Spring已经注册和扫描完成了,private final Map<String, BeanDefinition> beanDefinitionMap
中保存了该容器中的所有bean的BeanDefinition
。
2.5 单例Bean生成
我们进入org.springframework.context.support.AbstractApplicationContext#refresh
方法,该方法是创建Bean工厂和创建单例Bean的入口方法:
进入org.springframework.context.support.AbstractApplicationContext#finishBeanFactoryInitialization
:
2.6 遍历beanDefinitionNames、筛选出非懒加载且是单例的Bean、合并BeanDefinition
进入org.springframework.beans.factory.support.DefaultListableBeanFactory#preInstantiateSingletons
:
进入org.springframework.beans.factory.support.AbstractBeanFactory#getBean(java.lang.String)
:
进入org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean
:
进入org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#getSingleton(java.lang.String, org.springframework.beans.factory.ObjectFactory<?>)
:
我们先进入工厂方法org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBean(java.lang.String, org.springframework.beans.factory.support.RootBeanDefinition, java.lang.Object[])
:
进入org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean
,该方法才是创建Bean的最主要的方法。创建出来的Bean是封装在BeanWrapper中的,这是方便后面的填充Bean(依赖注入)和初始化Bean等操作:
2.7 推断构造方法
进入org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBeanInstance
:
该方法主要是推断构造方法,选择一个合适的构造方法去实例化Bean。推断规则请看【Spring】关于Spring的三种注入方式的分析的构造注入说明。
进入org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#instantiateBean
:
进入org.springframework.beans.factory.support.SimpleInstantiationStrategy#instantiate(org.springframework.beans.factory.support.RootBeanDefinition, java.lang.String, org.springframework.beans.factory.BeanFactory)
:
2.8 实例化(创建Bean)
进入org.springframework.beans.BeanUtils#instantiateClass(java.lang.reflect.Constructor<T>, java.lang.Object...)
:
到这里,bean对象已经实例化完成了,注意构造器注入也是发生在这一步操作。
2.9 填充Bean(依赖注入)
回到前面的org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean
方法中,我们进入org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#populateBean
:
其中getBeanPostProcessorCache().instantiationAware
是容器自定义的BeanPostProcessor
,我们看一下里面有什么:
CommonAnnotationBeanPostProcessor
处理@Resource
注解的属性注入和Setter注入;AutowiredAnnotationBeanPostProcessor
处理@Autowired
和@Value
注解的属性注入和Setter注入;
这两个都实现了org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor#postProcessProperties
,它们实现的代码是差不多的,我们看一下AutowiredAnnotationBeanPostProcessor
是如何实现这个方法的,进入org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor#postProcessProperties
:
进入org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor#findAutowiringMetadata
:
进入org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor#buildAutowiringMetadata
:
从这里看到,Spring针对属性注入和Setter注入时,是先查找属性,再查找方法,并把它们放入List集合中,所以就有属性注入先于Setter注入执行。
我们看一下查找的逻辑方法org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor#findAutowiredAnnotation
是怎样的:
autowiredAnnotationTypes
封装了AutowiredAnnotationBeanPostProcessor
能够处理的自动注入注解,我们看一下:
再回到前面的org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean
方法中,我们进入org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean(java.lang.String, java.lang.Object, org.springframework.beans.factory.support.RootBeanDefinition)
:
这个方法也是很重要的,主要是执行Ware接口的方法、初始化Bean以及初始化Bean前后的处理操作。
2.10 执行BeanXXXAware方法
我们进入org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#invokeAwareMethods
:
可以看到这里只执行BeanXXXAware
接口的方法,至于ApplicationContextAware
等接口,它们是由BeanPostProcessor
实现的。
2.11 执行BeanPostProcessor处理器的初始化前方法
返回再进入org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsBeforeInitialization
:
这里是主要就是执行每一个BeanPostProcessor处理器的初始化前方法。前面说ApplicationContextAware
等接口,它们是由BeanPostProcessor
实现的,我们先看getBeanPostProcessors()中有哪些BeanPostProcessor的bean:
可以看到有我们自定义的MyBeanPostProcessor
,其他的是容器自动给我们生成的。我们看一下ApplicationContextAwareProcessor
:
可以看到确实是实现使用BeanPostProcessor
处理器的方式实现的。
2.12 初始化Bean
返回再进入org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#invokeInitMethods
:
这里就是执行我们给Bean自定义的初始化方法。
2.13 执行BeanPostProcessor处理器的初始化后方法
在返回进入org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization
:
这个方法就是执行BeanPostProcessor处理器的初始化后方法。
到这里,这个Bean就算已经完成了初始化操作了,最后返回到org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#getSingleton(java.lang.String, org.springframework.beans.factory.ObjectFactory<?>)
中:
进入org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#addSingleton:
新创建的单例Bean放入singletonObjects
中,这时候我们就可以使用这个bean了。
2.14 执行销毁方法
在容器关闭时或者容器被销毁时,就会执行Bean的销毁方法。我们进入org.springframework.context.support.AbstractApplicationContext#destroyBeans
:
可以看到只会执行所有单例bean的销毁方法。
综上就是个人理解的Spring中Bean的生命周期,也许有些地方不够细节,后面有时间再补充。