阶段一:Bean元信息的配置阶段
该阶段就是用户对Bean信息的定义阶段。通过xml、注解、properties文件(一般不用)来定义Bean信息,或者使用API的方式即使用BeanDefinitionBuilder类直接构建BeanDefinition对象以定义Bean信息。BeanDefinition是表示Bean定义信息的接口,里面定义了一些获取bean定义配置信息的各种方法。不管用户以何种方式定义Bean,在后续阶段中都会将定义好的Bean信息组装成BeanDefinition并注册到容器中。
public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement {
/**
* 设置此bean的父bean名称(对应xml中bean元素的parent属性)
*/
void setParentName(@Nullable String parentName);
/**
* 返回此bean定义时指定的父bean的名称
*/
@Nullable
String getParentName();
/**
* 指定此bean定义的bean类名(对应xml中bean元素的class属性)
*/
void setBeanClassName(@Nullable String beanClassName);
/**
* 返回此bean定义的当前bean类名
* 注意,如果子定义重写/继承其父类的类名,则这不一定是运行时使用的实际类名。此外,这可能只是调用工厂方法的类,或者在调用方法的工厂bean引用的情况下,它甚至可能是空的。因此,不要认为这是运行时的最终bean类型,而只将其用于单个bean定义级别的解析目的。
*/
@Nullable
String getBeanClassName();
/**
* 设置此bean的生命周期,如:singleton、prototype(对应xml中bean元素的scope属性)
*/
void setScope(@Nullable String scope);
/**
* 返回此bean的生命周期,如:singleton、prototype
*/
@Nullable
String getScope();
/**
* 设置是否应延迟初始化此bean(对应xml中bean元素的lazy属性)
*/
void setLazyInit(boolean lazyInit);
/**
* 返回是否应延迟初始化此bean,只对单例bean有效
*/
boolean isLazyInit();
/**
* 设置此bean依赖于初始化的bean的名称,bean工厂将保证dependsOn指定的bean会在当前bean初始化之前先初始化好
*/
void setDependsOn(@Nullable String... dependsOn);
/**
* 返回此bean所依赖的bean名称
*/
@Nullable
String[] getDependsOn();
/**
* 设置此bean是否作为其他bean自动注入时的候选者
* autowireCandidate
*/
void setAutowireCandidate(boolean autowireCandidate);
/**
* 返回此bean是否作为其他bean自动注入时的候选者
*/
boolean isAutowireCandidate();
/**
* 设置此bean是否为自动注入的主要候选者
* primary:是否为主要候选者
*/
void setPrimary(boolean primary);
/**
* 返回此bean是否作为自动注入的主要候选者
*/
boolean isPrimary();
/**
* 指定要使用的工厂bean(如果有)。这是要对其调用指定工厂方法的bean的名称。
* factoryBeanName:工厂bean名称
*/
void setFactoryBeanName(@Nullable String factoryBeanName);
/**
* 返回工厂bean名称(如果有)(对应xml中bean元素的factory-bean属性)
*/
@Nullable
String getFactoryBeanName();
/**
* 指定工厂方法(如果有)。此方法将使用构造函数参数调用,如果未指定任何参数,则不使用任何参数调用。该方法将在指定的工厂bean(如果有的话)上调用,或者作为本地bean类上的静态方法调用。
* factoryMethodName:工厂方法名称
*/
void setFactoryMethodName(@Nullable String factoryMethodName);
/**
* 返回工厂方法名称(对应xml中bean的factory-method属性)
*/
@Nullable
String getFactoryMethodName();
/**
* 返回此bean的构造函数参数值
*/
ConstructorArgumentValues getConstructorArgumentValues();
/**
* 是否有构造器参数值设置信息(对应xml中bean元素的<constructor-arg />子元素)
*/
default boolean hasConstructorArgumentValues() {
return !getConstructorArgumentValues().isEmpty();
}
/**
* 获取bean定义是配置的属性值设置信息
*/
MutablePropertyValues getPropertyValues();
/**
* 这个bean定义中是否有属性设置信息(对应xml中bean元素的<property />子元素)
*/
default boolean hasPropertyValues() {
return !getPropertyValues().isEmpty();
}
/**
* 设置bean初始化方法名称
*/
void setInitMethodName(@Nullable String initMethodName);
/**
* bean初始化方法名称
*/
@Nullable
String getInitMethodName();
/**
* 设置bean销毁方法的名称
*/
void setDestroyMethodName(@Nullable String destroyMethodName);
/**
* bean销毁的方法名称
*/
@Nullable
String getDestroyMethodName();
/**
* 设置bean的role信息
*/
void setRole(int role);
/**
* bean定义的role信息
*/
int getRole();
/**
* 设置bean描述信息
*/
void setDescription(@Nullable String description);
/**
* bean描述信息
*/
@Nullable
String getDescription();
/**
* bean类型解析器
*/
ResolvableType getResolvableType();
/**
* 是否是单例的bean
*/
boolean isSingleton();
/**
* 是否是多列的bean
*/
boolean isPrototype();
/**
* 对应xml中bean元素的abstract属性,用来指定是否是抽象的
*/
boolean isAbstract();
/**
* 返回此bean定义来自的资源的描述(以便在出现错误时显示上下文)
*/
@Nullable
String getResourceDescription();
@Nullable
BeanDefinition getOriginatingBeanDefinition();
}
阶段二:Bean元信息的解析阶段
通过XmlBeanDefinitionReader、PropertiesBeanDefinitionReader、AnnotatedBeanDefinitionReader将阶段一中各种方式定义好的bean配置信息解析为BeanDefinition对象。
阶段三:Spring Bean注册阶段
通过BeanDefinitionRegistry接口来注册Bean。
public interface BeanDefinitionRegistry extends AliasRegistry {
/**
* 注册一个新的bean定义
* beanName:bean的名称
* beanDefinition:bean定义信息
*/
void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
throws BeanDefinitionStoreException;
/**
* 通过bean名称移除已注册的bean
* beanName:bean名称
*/
void removeBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;
/**
* 通过名称获取bean的定义信息
* beanName:bean名称
*/
BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;
/**
* 查看beanName是否注册过
*/
boolean containsBeanDefinition(String beanName);
/**
* 获取已经定义(注册)的bean名称列表
*/
String[] getBeanDefinitionNames();
/**
* 返回注册器中已注册的bean数量
*/
int getBeanDefinitionCount();
/**
* 确定给定的bean名称或者别名是否已在此注册表中使用
* beanName:可以是bean名称或者bean的别名
*/
boolean isBeanNameInUse(String beanName);
}
BeanDefinitionRegistry接口继承了AliasRegistry接口,这个接口中定义了操作bean别名的一些方法
public interface AliasRegistry {
/**
* 给name指定别名alias
*/
void registerAlias(String name, String alias);
/**
* 从此注册表中删除指定的别名
*/
void removeAlias(String alias);
/**
* 判断name是否作为别名已经被使用了
*/
boolean isAlias(String name);
/**
* 返回name对应的所有别名
*/
String[] getAliases(String name);
}
DefaultListableBeanFactory是BeanDefinitionRegistry接口的唯一实现类。
阶段四:BeanDefinition合并阶段
当定义Bean的时候包含父子Bean关系,子Bean的定义信息是不完全的,有一部分定义信息是继承自父Bean,因此需要合并父子BeanDefinition,最终得到一个RootBeanDefinition,其包含了bean定义的所有信息,包含了从父bean中继继承过来的所有信息,后续bean的所有创建工作就是依靠合并之后BeanDefinition来进行。
BeanDefinition的合并使用的是此方法:
org.springframework.beans.factory.support.AbstractBeanFactory#getMergedBeanDefinition
需要注意的是,Bean的定义可能存在多级父子关系,合并的时候进进行递归合并,最终得到一个包含完整信息的RootBeanDefinition
阶段五:Bean的Class加载阶段
这个阶段就是将bean的class名称转换为Class类型的对象。 当BeanDefinition对象中的beanClass属性值是该类的全限定名时,使用类加载器加载全限定名得到该类的字节码对象。
该阶段使用的是如下方法:
org.springframework.beans.factory.support.AbstractBeanFactory#resolveBeanClass
阶段六:Bean实例化阶段
该阶段分为两小阶段:Bean实例化前操作和Bean实例化操作
DefaultListableBeanFactory类中有个重要字段
private final List<BeanPostProcessor> beanPostProcessors = new CopyOnWriteArrayList<>();,该字段是BeanPostProcess类的集合。BeanPostProcessor接口及其子接口提供了对Spring生命周期中扩展点的处理,bean生命周期中的所有扩展点都是依靠这个集合中的BeanPostProcessor来实现的。
实例化前
在Bean实例化之前会调用applyBeanPostProcessorsBeforeInstantiation方法:
@Nullable
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
if (result != null) {
return result;
}
}
}
return null;
}
该方法为开发者提供了实例化前的扩展点,开发者自己可以在这个地方直接去创建一个对象作为bean实例,而跳过spring内部实例化bean的过程。
上面代码中轮询beanPostProcessors列表,如果类型是InstantiationAwareBeanPostProcessor, 尝试调用InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation获取bean的实例对象,如果能够获取到,那么将返回值作为当前bean的实例,那么spring自带的实例化bean的过程就被跳过了。
postProcessBeforeInstantiation方法如下:
default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
return null;
}
Bean的实例化阶段
该阶段通过反射调用类的构造器实例化Bean。Spring提供了接口允许开发者自己判断具体调用哪个构造器。
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
Constructor<?>[] ctors = ibp.determineCandidateConstructors(beanClass, beanName);
if (ctors != null) {
return ctors;
}
}
}
会调用SmartInstantiationAwareBeanPostProcessor接口的determineCandidateConstructors方法,这个方法会返回候选的构造器列表,也可以返回空,看一下这个方法的源码:
@Nullable
default Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, String beanName)
throws BeansException {
return null;
}
阶段七:合并后的BeanDefinition处理
protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof MergedBeanDefinitionPostProcessor) {
MergedBeanDefinitionPostProcessor bdp = (MergedBeanDefinitionPostProcessor) bp;
bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName);
}
}
}
pring会轮询BeanPostProcessor,依次调用MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition
void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName);
第一个参数为beanDefinition,表示合并之后的RootBeanDefinition,我们可以在这个方法内部对合并之后的BeanDefinition进行再次处理。
MergedBeanDefinitionPostProcessor有2个实现类:
org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor
在 postProcessMergedBeanDefinition 方法中对 @Autowired、@Value 标注的方法、字段进行缓存
org.springframework.context.annotation.CommonAnnotationBeanPostProcessor
在 postProcessMergedBeanDefinition 方法中对 @Resource 标注的字段、@Resource 标注的方法、 @PostConstruct 标注的字段、 @PreDestroy标注的方法进行缓存
阶段八:Bean的属性设置阶段
该阶段分为三个小阶段:实例化后阶段、Bean属性赋值前处理阶段、Bean属性赋值阶段
实例化后阶段
调用InstantiationAwareBeanPostProcessor接口的postProcessAfterInstantiation这个方法。
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
return;
}
}
}
default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
return true;
}
当postProcessAfterInstantiation方法返回false的时候,后续的Bean属性赋值前处理、Bean属性赋值都会被跳过。
Bean属性赋值前处理阶段
这个阶段会调用InstantiationAwareBeanPostProcessor接口的postProcessProperties方法
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
if (filteredPds == null) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
return;
}
}
pvs = pvsToUse;
}
}
@Nullable
default PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName)
throws BeansException {
return null;
}
从上面可以看出,如果InstantiationAwareBeanPostProcessor中的postProcessProperties和postProcessPropertyValues都返回空的时候,表示这个bean不需要设置属性,直接返回了,直接进入下一个阶段。PropertyValues中保存了bean实例对象中所有属性值的设置,所以我们可以在这个这个方法中对PropertyValues值进行修改。
Bean属性赋值阶段
循环处理PropertyValues中的属性值信息,通过反射调用set方法将属性的值设置到bean实例中。PropertyValues中的值是通过bean xml中property元素配置的,或者调用MutablePropertyValues中add方法设置的值。
阶段九:Bean初始化阶段
该阶段分为五个小阶段:
- Bean Aware接口回调
- Bean初始化前操作
- Bean初始化操作
- Bean初始化后操作
- Bean初始化完成操作
Bean Aware 接口回调
private void invokeAwareMethods(final String beanName, final Object bean) {
if (bean instanceof Aware) {
if (bean instanceof BeanNameAware) {
((BeanNameAware) bean).setBeanName(beanName);
}
if (bean instanceof BeanClassLoaderAware) {
ClassLoader bcl = getBeanClassLoader();
if (bcl != null) {
((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
}
}
if (bean instanceof BeanFactoryAware) {
((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
}
}
}
如果我们的bean实例实现了上面的接口,会按照下面的顺序依次进行调用:
- BeanNameAware:将bean的名称注入进去
- BeanClassLoaderAware:将BeanClassLoader注入进去
- BeanFactoryAware:将BeanFactory注入进去
Bean初始化前操作
@Override
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor.postProcessBeforeInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
会调用BeanPostProcessor的postProcessBeforeInitialization方法,若返回值为null,当前方法将结束。
通常称postProcessBeforeInitialization这个方法为:bean初始化前操作。
这个接口有2个实现类,比较重要:
org.springframework.context.support.ApplicationContextAwareProcessor org.springframework.context.annotation.CommonAnnotationBeanPostProcessor
ApplicationContextAwareProcessor注入6个Aware接口对象
如果bean实现了下面的接口,在ApplicationContextAwareProcessor#postProcessBeforeInitialization中会依次调用下面接口中的方法,将Aware前缀对应的对象注入到bean实例中。
- EnvironmentAware:注入Environment对象
- EmbeddedValueResolverAware:注入EmbeddedValueResolver对象
- ResourceLoaderAware:注入ResourceLoader对象
- ApplicationEventPublisherAware:注入ApplicationEventPublisher对象
- MessageSourceAware:注入MessageSource对象
- ApplicationContextAware:注入ApplicationContext对象
从名称上可以看出这个类以
ApplicationContext开头的,说明这个类只能在ApplicationContext环境中使用。
CommonAnnotationBeanPostProcessor调用@PostConstruct标注的方法
CommonAnnotationBeanPostProcessor#postProcessBeforeInitialization中会调用bean中所有标注@PostConstruct注解的方法。
Bean初始化操作
该阶段有两个步骤:
- 调用InitializingBean接口的afterPropertiesSet方法
- 调用定义bean的时候指定的初始化方法。
调用InitializingBean接口的afterPropertiesSet方法
public interface InitializingBean {
void afterPropertiesSet() throws Exception;
}
当Bean实现了这个接口,会在该阶段被调用。
调用bean定义的时候指定的初始化方法
指定Bean的初始化方式有三种:
-
xml方式指定初始化方法
<bean init-method="bean中方法名称"/> -
@Bean的方式指定初始化方法
@Bean(initMethod = "初始化的方法") -
Api的方式指定初始化方法
this.beanDefinition.setInitMethodName(methodName);
初始化方法最终会赋值给下面这个字段
org.springframework.beans.factory.support.AbstractBeanDefinition#initMethodName
Bean初始化后操作
@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor.postProcessAfterInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
调用BeanPostProcessor的postProcessAfterInitialization方法,若返回值为null则方法结束。 通常称postProcessAfterInitialization这个方法为:bean初始化后置操作。
Bean初始化完成操作
上述步骤完成后Bean的初始化完成,进入下个阶段
阶段十:所有单例Bena初始化完成后阶段
所有单例bean实例化完成之后,spring会回调下面这个接口:
public interface SmartInitializingSingleton {
void afterSingletonsInstantiated();
}
调用逻辑在下面这个方法中:
/**
* 确保所有非lazy的单例都被实例化,同时考虑到FactoryBeans。如果需要,通常在工厂设置结束时调用。
*/
org.springframework.beans.factory.support.DefaultListableBeanFactory#preInstantiateSingletons
该方法会触发所有非lazy-init的单例Bean的初始化,然后在容器中找到所有类型是SmartInitializingSingleton的Bean,调用它们的afterSingletoninstantiated方法。
阶段十一:Bean的使用阶段
调用getBean方法得到Bean进行使用。
阶段十二:Bean的销毁阶段
触发bean销毁的几种方式
- 调用org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#destroyBean
- 调用org.springframework.beans.factory.config.ConfigurableBeanFactory#destroySingletons
-
调用ApplicationContext中的close方法
Bean销毁阶段会依次执行
- 轮询beanPostProcessors列表,如果是DestructionAwareBeanPostProcessor这种类型的,会调用其内部的postProcessBeforeDestruction方法。
DestructionAwareBeanPostProcessor接口有实现类CommonAnnotationBeanPostProcessor,该类中的postProcessBeforeDestruction方法会调用Bean中所有标注了@PreDestroy注解的方法。
- 如果bean实现了org.springframework.beans.factory.DisposableBean接口,会调用这个接口中的destroy方法
- 调用bean自定义的销毁方法,有三种方式:
方式1:xml中指定销毁方法
<bean destroy-method="bean中方法名称"/>
方式2:@Bean中指定销毁方法
@Bean(destroyMethod = "初始化的方法")
方式3:api的方式指定销毁方法
this.beanDefinition.setDestroyMethodName(methodName);
初始化方法最终会赋值给下面这个字段
org.springframework.beans.factory.support.AbstractBeanDefinition#destroyMethodName
销毁方法的调用顺序:
- @PreDestroy标注的所有方法
- DisposableBean接口中的destroy()
- 自定义的销毁方法