流程图:
共有13个阶段
一、Bean元信息配置阶段
Bean信息定义有4中方式
- API方式
- Xml文件方式
- Properties文件方式
- 注解方式
API方式:
是通过实现BeanDefinition接口的方式,具体的实现类有5种:
- RootBeanDefinition:根bean定义信息。表示没有父bean的bean
- ChildBeanDefinition:子bean定义信息。需要通过parentName属性来指定父bean
- GenericBeanDefinition:通用bean定义信息。既可以表示没有父bean的bean,也可以表示有父bean的子bean信息。也有parent属性。
- ConfigurationClassBeanDefinition:配置类中@bean方法定义的bean信息。
- AnnotatedGenercBeanDefinition:通过注解方式定义的bean信息
直接实例化即可。
Xml方式:
<bean id="bean名称">
<constructor-arg index="0" value="bean的值" ref="引用的bean名称" />
</bean>
最终也会通过XmlBeanDefinitionReader类解析成API的配置方式
Properties文件方式:
employee.(class)=MyClass // 等同于:<bean class="MyClass" />
employee.(abstract)=true // 等同于:<bean abstract="true" />
employee.group=Insurance // 为属性设置值,等同于:<property name="group" value="Insurance" />
employee.usesDialUp=false // 为employee这个bean中的usesDialUp属性设置值,等同于:等同于:<property name="usesDialUp" value="false" />
最终也会通过 PropertiesBeanDefinitionReader类解析成API的配置方式
注解方式:
@bean或@Compontent最终也会解析成API的配置方式
二、Bean元信息解析阶段
元信息解析主要有3中方式:
- xml文件定义bean的解析(XmlBeanDefinitionReader)
- properties文件定义bean的解析(PropertiesBeanDefinitionReader)
- 注解方式定义bean的解析(PropertiesBeanDefinitionReader)
三、将Bean注册到容器中
bean注册接口:BeanDefinitionRegistry (继承了AliasRegistry
)
别名注册接口:AliasRegistry
前三步是在创建ioc容器的时候发生,下面四步到十步是在getBean的时候发生
四、BeanDefinition合并阶段
bean定义可能存在多级的父子关系,递归合并成一个包含完整信息的RootBeanDefinition。
合并处的源码如下:
之后的阶段将使用这个RootBeanDefinition,下一步将检查是否需要加载依赖Bean,没有则跳过(图未截取全)
五、Bean Class加载阶段
将bean的class名称转换为Class类型的对象。
源码如下:
具体的resolveBeanClass方法,往下深入,可以看到最终是通过Class.forName获取的类对象
有了类对象下面就可以开始通过反射进行实例化了
六、Bean实例化阶段
(1)实例化之前
会执行实现了BeanPostProcesstor接口的类的postProcessBeforeInitialization方法。
源码如下:
可以看出,如果返回了Bean,则spring就会直接使用此bean,而跳过下面创建bean的操作了(这是spring的一个扩展点)
(2)实例化
这个过程会通过反射来调用bean的构造器来创建bean的实例,最后包装成BeanWrapper。(使用了装饰器模式)
源码如下:
这里使用了策略模式,在SimpleInstantiationStrategy类中处理
最后在BeanUtils类的InstantiateClass方法中调用的类的newInstance方法(核心)
七、合并后的BeanDefinition处理
后置处理类进行一些缓存处理,方便后面使用
主要是对实现了MergedBeanDefinitionPostProcessor这个接口的类进行回调处理,实现类主要包括:
- AutowiredAnnotationBeanPostProcessor 对@Autowired和@Value标注的字段或方法 进行缓存处理,方便后面使用
- CommonAnnotationBeanPostProcessor 对@Resource标注的字段或方法、@PostConstruct标注的方法、@PerDestroy标注的方法进行缓存处理
八、属性赋值阶段
(1)实例化后阶段
spring会调用实现了InstantiationAwareBeanPostProcessor接口的类的postProcessAfterInstantiation方法
如果返回false,则后面的两步属性赋值就会跳过。所以可以用来阻止属性赋值
(2)Bean属性赋值前阶段
主要是通过@Autowire等注解生成属性的值,以便后面进行赋值
可以看出当postProcessProperties和postProcessPropertyValues都返回空时,表示此bean不需要设置属性,直接返回,进入下一阶段。
PropertyValues中保存了bean实例对象中所有属性值的设置,所以我们可以在这个postProcessProperties中对PropertyValues值进行修改
InstantiationAwareBeanPostProcessor的实现类如下:
最关键是这两个实现类值的注入操作:
- AutowiredAnnotationBeanPostProcessor 对@Autowired和@Value标注的字段或方法注入值
- CommonAnnotationBeanPostProcessor 对@Resource标注的字段或方法注入值
(3)bean的属性赋值阶段
循环处理PropertyValues
中的属性值信息,通过反射调用set方法将属性的值设置到bean实例中。
九曲十八弯之后,最终调用的是BeanWrapperImpl的setValue方法中通过反射为字段赋值
九、Bean初始化阶段
(1)Bean Aware接口回调
(2)Bean初始化前操作
spring会调用实现了BeanPostProcessor接口的实现类的postProcessBeforeInitialization方法。
实现类包括很多(没截全)
最关键的是
- ApplicationContextAwareProcessor 它会注入6个Aware。包括:EnvironmentAware、EmbeddedValueResolverAware、ResourceLoaderAware、ApplicationEventPublisherAware、MessageSourceAware、ApplicationContextAware。因为只有ApplicationContext环境才能使用这些
- InitDestroyAnnotationBeanPostProcessor 它用来调用所有注解了@PostConstrust的方法
(3)Bean初始化操作
1、调用实现了InitializingBean接口的Bean的afterPropertiesSet方法
2、调用定义bean的时候指定的init-method初始化方法。
有三种方式指定初始化方法:
- xml方法指定 <bean init-method="bean中方法名称"/>
- @bean方法指定 @Bean(initMethod = "初始化的方法")
- api的方法指定 beanDefinition.setInitMethodName(methodName);
(4)Bean初始化后操作
spring会调用实现了BeanPostProcessor接口的实现类的postProcessAfterInitialization方法。
十、bean初始化完成后阶段
为了确保所有非lazy的单例都被实例化,同时考虑到FactoryBeans
所以在全部bean初始化完成之后,spring会初始化实现了SmartInitializingSingleton接口的afterSingletonsInstantiated方法。
也包括BeanFactory自身。
带有ApplicationContext的容器,内部最终都会调用preInstantiateSingletons触发所有单例bean的初始化。
十一、Bean使用阶段
不必多说
十二、Bean销毁前阶段
bean的销毁有三种方式:
- AbstractAutowireCapableBean类的destoryBean方法
- ConfigurableBeanFactory类的destorySingletons方法
- ApplicationContext的close方法
Bean销毁阶段会依次执行:
-
轮询beanPostProcessors列表,如果是DestructionAwareBeanPostProcessor这种类型的,会调用其内部的postProcessBeforeDestruction方法
-
如果bean实现了org.springframework.beans.factory.DisposableBean接口,会调用这个接口中的destroy方法
-
调用bean自定义的销毁方法
spring会调用实现了DestructionAwareBeanPostProcessor接口的类的postProcessBeforeDestruction方法
实现类如下:
最关键的是:
- CommonAnnotationBeanPostProcessor 它会调用bean中所有标注了@PreDestroy的方法
十三、Bean销毁阶段
自定义销毁方法有3种方式:
- xml中指定销毁方法 <bean destroy-method="bean中方法名称"/>
- @Bean中指定销毁方法 @Bean(destroyMethod = "初始化的方法")
- api的方式指定销毁方法 beanDefinition.setDestroyMethodName(methodName);