前一篇文章讲解了beanFactory的初始化流程,这篇文章我们接着往下分析spring bean的实例化及初始化流程
入口点:
ClassPathXmlApplicationContext cs=new ClassPathXmlApplicationContext("xxx");
cs.getBean("bean1");
public Object getBean(String name) throws BeansException {
return this.doGetBean(name, (Class)null, (Object[])null, false);
}
0.流程图总结
1.bean整体流程:
2.加载流程
3.实列化流程
4.初始化流程
1.bean初始化流程:
(1)转换对应的beanName
这里传入的参数name并不一定是beanName,可能是别名,也可能是FactoryBean,所以进行一系列的解析,这些解析内容如下
1)去除FactoryBean的修饰符,也就是name="&aa",那么首先会去除&,而使name=aa
2)取指定别名所表示的最终的beanName
(2)尝试从缓存中加载单例
单例在spring的同一个容器内只会被创建一次,后续在获取bean,就直接从单例缓存中获取了,当然,这里也只是尝试加载,
首先尝试从缓存中加载,如果加载不成功则再次尝试从singletonFactories中加载。因为在创建单例bean的时候会存在依赖注入的情况
而在创建依赖的时候为了避免循环依赖,在spring中创建bean的原则是不等bean创建完成就会将创建bean的ObjectFactory提早曝光加入
到缓存中,一旦下一个bean创建的时候需要依赖上一个bean则直接使用ObjectFactory
(3)bean的实例化
如果缓存中得到了bean的原始状态,则需要对bean进行实例化,缓存中的记录只是最原始的bean状态,并不一定是我们最终想要的bean,
举个例子,假如我们想对工厂bean进行处理,那么这里得到的是工厂bean的初始状态,但是我们真正想要的是工厂bean定义的factory-method
方法中返回的bean,而getObjectForBeanInstance就是完成这个工作的
(4)原型模式的依赖检查
只有在单例情况下才会尝试解决循环依赖,如果存在A中有B的属性,B中有A的属性,那么当依赖注入的时候,就会产生当A还没创建完成的时候,因为
对B的创建再次返回创建A,造成循环依赖,也就是(isPrototypeCurrentlyInCreation(beanName))为true的情况
(5)检测parentBeanFactory
从代码上看,如果缓存没有数据的话,直接转到父类工厂上去加载了,这是为什么?可能我们忽略了
parentBeanFactory != null && !containsBeanDefinition(beanName)这里面判断条件,parentBeanFactory != null,parentBeanFactory如果为空,
其他一切都是浮云,但是还有一个条件,!containsBeanDefinition(beanName),它是在检测如果当前加载的XML配置文件中,不包含beanName多对应的
配置,只能去parentBeanFactory中尝试,然后再去递归的调用递归方法
(6)将存储XML配置文件GenericBeanDefinition转换为RootBeanDefinition
因为从XML配置文件中读取到的bean信息存储在GenericBeanDefinition中,但是所有的bean的后续处理都是针对于RootBeanDefinition,
所以这里需要进行一个转换,转换的同时,如果父类bean不为空的话,则会一并合并父类属性
(7)寻找依赖
因为bean的初始化过程很肯能用到某些属性,而某些属性可能是动态配置的,并且配置成依赖其他的bean,那么这个时候必须先加载依赖的bean,
spring的加载顺序中,在初始化一个bean的时候,首先会初始化这个bean所对应的依赖
(8)针对不同的scope进行bean的创建
spring根据不同的配置进行不同的初始化策略,默认的是singleton
(9)类型转换
程序到这里已经基本结束了,通常对该方法的调用参数requireType是为空的,但是可能会存在这样的情况,返回的bean其实是个String,但是
requireType却传入的是Integer类型,那么这时候本步骤就起作用了,他的功能是将返回的bean转换为requireType所指定的类型。
代码:
protected <T> T doGetBean(String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly) throws BeansException {
String beanName = this.transformedBeanName(name);
Object sharedInstance = this.getSingleton(beanName);
Object bean;
if (sharedInstance != null && args == null) {
if (this.logger.isTraceEnabled()) {
if (this.isSingletonCurrentlyInCreation(beanName)) {
this.logger.trace("Returning eagerly cached instance of singleton bean '" + beanName + "' that is not fully initialized yet - a consequence of a circular reference");
} else {
this.logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
}
}
bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, (RootBeanDefinition)null);
} else {
if (this.isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
BeanFactory parentBeanFactory = this.getParentBeanFactory();
if (parentBeanFactory != null && !this.containsBeanDefinition(beanName)) {
String nameToLookup = this.originalBeanName(name);
if (parentBeanFactory instanceof AbstractBeanFactory) {
return ((AbstractBeanFactory)parentBeanFactory).doGetBean(nameToLookup, requiredType, args, typeCheckOnly);
}
if (args != null) {
return parentBeanFactory.getBean(nameToLookup, args);
}
if (requiredType != null) {
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
return parentBeanFactory.getBean(nameToLookup);
}
if (!typeCheckOnly) {
this.markBeanAsCreated(beanName);
}
try {
RootBeanDefinition mbd = this.getMergedLocalBeanDefinition(beanName);
this.checkMergedBeanDefinition(mbd, beanName, args);
String[] dependsOn = mbd.getDependsOn();
String[] var11;
if (dependsOn != null) {
var11 = dependsOn;
int var12 = dependsOn.length;
for(int var13 = 0; var13 < var12; ++var13) {
String dep = var11[var13];
if (this.isDependent(beanName, dep)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
this.registerDependentBean(dep, beanName);
try {
this.getBean(dep);
} catch (NoSuchBeanDefinitionException var24) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "'" + beanName + "' depends on missing bean '" + dep + "'", var24);
}
}
}
if (mbd.isSingleton()) {
sharedInstance = this.getSingleton(beanName, () -> {
try {
return this.createBean(beanName, mbd, args);
} catch (BeansException var5) {
this.destroySingleton(beanName);
throw var5;
}
});
bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
} else if (mbd.isPrototype()) {
var11 = null;
Object prototypeInstance;
try {
this.beforePrototypeCreation(beanName);
prototypeInstance = this.createBean(beanName, mbd, args);
} finally {
this.afterPrototypeCreation(beanName);
}
bean = this.getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
} else {
String scopeName = mbd.getScope();
Scope scope = (Scope)this.scopes.get(scopeName);
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
}
try {
Object scopedInstance = scope.get(beanName, () -> {
this.beforePrototypeCreation(beanName);
Object var4;
try {
var4 = this.createBean(beanName, mbd, args);
} finally {
this.afterPrototypeCreation(beanName);
}
return var4;
});
bean = this.getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
} catch (IllegalStateException var23) {
throw new BeanCreationException(beanName, "Scope '" + scopeName + "' is not active for the current thread; consider defining a scoped proxy for this bean if you intend to refer to it from a singleton", var23);
}
}
} catch (BeansException var26) {
this.cleanupAfterBeanCreationFailure(beanName);
throw var26;
}
}
if (requiredType != null && !requiredType.isInstance(bean)) {
try {
T convertedBean = this.getTypeConverter().convertIfNecessary(bean, requiredType);
if (convertedBean == null) {
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
} else {
return convertedBean;
}
} catch (TypeMismatchException var25) {
if (this.logger.isTraceEnabled()) {
this.logger.trace("Failed to convert bean '" + name + "' to required type '" + ClassUtils.getQualifiedName(requiredType) + "'", var25);
}
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
} else {
return bean;
}
}
2.着一刨析
1.factoryBean的使用
一般情况下,spring通过反射机制,利用bean的class属性指定实现类来实例化bean。在某些情况下,实例化bean的过程比较复杂,按照传统的方式,
则需要在bean的配置中提供大量的配置信息,配置方式的灵活性是受限的,spring为此提供了一个org.springframework.beans.factory.FactoryBean
工厂类接口,用户可以实现该接口定制实例化bean的逻辑
FactoryBean接口对于spring来说,占有重要地位,spring自身就提供了70多个FactoryBean的实现,从spring 3.0开始,FactoryBean开始支持泛型
接口声明为:
[[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-l3RigUj7-1604735670458)(D:\Typora\java核心\A源码专题\spring\assets\copycode.gif)]](javascript:void(0)😉
public interface FactoryBean<T> {
T getObject() throws Exception;
Class<?> getObjectType();
default boolean isSingleton() {
return true;
}
}
[[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9mzhx4HK-1604735670458)(D:\Typora\java核心\A源码专题\spring\assets\copycode.gif)]](javascript:void(0)😉
接口中定义的三个方法:
1)T getObject():返回由FactoryBean创建的bean实例,如果isSignleton()返回的是true,则该实例会方放到spring容器中单实例缓存池中
2)default boolean isSingleton():判断创建bean的scope
3)Class<?> getObjectType():返回创建bean的类型
2.缓存中获取单列bean
单例在spring的同一容器中只会被创建一次,然后再获取bean直接从单例缓存中获取,当然,这里也只是尝试加载,首先尝试从缓存中加载,
然后再次尝试从singletonFactories中加载,因为在创建单例bean的时候会存在依赖注入的情况,而在创建依赖的时候为了避免循环依赖,
spring创建bean的原则是不等bean创建完成就会将创建bean的ObjectFactory提早曝光加入到缓存中,一旦下一个bean创建的时候依赖上个bean
则直接使用ObjectFactory
下面的额源码是在org.springframework.beans.factory.support包下DefaultSingletonBeanRegistry中
[[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tT6uHz9R-1604735670459)(D:\Typora\java核心\A源码专题\spring\assets\copycode-1603886920601.gif)]](javascript:void(0)😉
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
// 检查缓存中是否存在实例
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
// 如果为空,则锁定全局变量并进行处理
synchronized (this.singletonObjects) {
// 如果此bean正在加载则不处理
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
// ObjectFactory初始化策略存储在singletonFactories
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
// 调用预先设定好的getObject()方法
singletonObject = singletonFactory.getObject();
// 记录在缓存中earlySingletonObjects和singletonFactories互斥
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
return singletonObject;
}
[](javascript:void(0)😉
这个方法首先尝试从singletonObjects里面获取实例,如果获取不到,再从earlySingletonObjects中获取,如果还获取不到,尝试从
singletonFactories中获取beanName对应的ObjectFactory,然后调用这个ObjectFactory的getObject()来创建bean,并放到earlySingletonObjects中去,
并且从singletonFactories中remove掉ObjectFactory,而对于后续的所有内存操作都只为了循环依赖检测时候使用,这里有几个不同的map:
singletonObjects:用于保存BeanName和创建bean实例之间的关系,bean name -> bean instance
singletonFactories:用于保存BeanName和创建bean工厂之间的关系,bean name -> ObjectFactory
earlySingletonObjects:用于保存BeanName和创建bean实例之间的关系,与ingletonObjects不同的是,当一个单例bean被放到这里面后,那么当bean
还在创建过程中,就可以通过getBean方法获取到了,其目的是用来检测循环引用
registeredSingletons:用来保存所有当前已存在的bean
private final Map<String, Object> singletonObjects = new ConcurrentHashMap(256);
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap(16);
private final Map<String, Object> earlySingletonObjects = new HashMap(16);
private final Set<String> registeredSingletons = new LinkedHashSet(256);
3.factoryBean类型的实列化
在doGetBean()方法中,getObjectForBeanInstance是个高频使用的方法,无论是从缓存中获取bean还是根据不同的scope策略加载bean,总之,得到bean的实例后,我们第一步要做的就是调用这个方法来检测一下正确性,其实就是用于检测当前bean是否是FactoryBean类型的bean,如果是,那么需要调用该
bean对应的FactoryBean实例中的getObject()作为返回值
无论是从缓存中获取到bean还是从不同的scope策略中加载的bean都是最原始的bean状态,并不一定是我们最终想要的bean,而getObjectForBeanInstance方法就是完成这个工作的,该方法内部最后调用了facotry.getBean()来返回我们希望的得到的bean
4.加载bean
之前我们讲解了从缓存中获取单例的过程,那么,如果缓存中不存在已经加载的单例bean,就需要从头开始bean的加载过程了,而spring中使用了
getSingleton()的重载方法实现bean的加载过程
sharedInstance = this.getSingleton(beanName, () -> {
try {
return this.createBean(beanName, mbd, args);
} catch (BeansException var5) {
this.destroySingleton(beanName);
throw var5;
}
});
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(beanName, "Bean name must not be null");
// 全局变量需要同步
synchronized (this.singletonObjects) {
// 首先检查对应的bean是否已经加载过,因为singleton模式其实就是复用以创建的bean,所以这一步是必须的
Object singletonObject = this.singletonObjects.get(beanName);
// 如果为空才可以进行singleton的bean的初始化
if (singletonObject == null) {
beforeSingletonCreation(beanName);
boolean newSingleton = false;
boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
if (recordSuppressedExceptions) {
this.suppressedExceptions = new LinkedHashSet<>();
}
try {
// 初始化bean
singletonObject = singletonFactory.getObject();
newSingleton = true;
}
finally {
if (recordSuppressedExceptions) {
this.suppressedExceptions = null;
}
afterSingletonCreation(beanName);
}
if (newSingleton) {
// 加入缓存中
addSingleton(beanName, singletonObject);
}
}
return singletonObject;
}
}
[](javascript:void(0)😉
上述代码中其实使用了回调方法,使得程序可以在单例创建的前后做一些准备及处理操作,而真正的获取单例bean的方法其实并不是在此方法中实现,
其逻辑是在ObjectFactory类型的实例singletonFactory中实现的,而这些准备和处理操作包括如下:
(1)检查缓存中是否已经加载过
(2)若没有加载,则记录beanName的正在加载状态
(3)加载单例前记录加载状态
可能你会觉得beforeSingletonCreation方法是个空实现,里面没有任何逻辑,但其实不是,这个函数中做了一个很重要的操作:记录加载状态,也就是
通过this.singletonsCurrentlyInCreation.add(beanName)将当前正要创建的bean记录在缓存中,这样就可以对循环依赖进行检测 同一个类中
protected void beforeSingletonCreation(String beanName) {
if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
}
(4)通过调用参数传入的ObjectFactory的个体Object方法实例化bean
(5)加载单例后的处理方法调用
同步骤3的记录加载状态相似,当bean加载结束后需要移除缓存中对该bean的正在加载状态的记录,同一个类中
protected void afterSingletonCreation(String beanName) {
if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.remove(beanName)) {
throw new IllegalStateException("Singleton '" + beanName + "' isn't currently in creation");
}
}
(6)将结果记录至缓存并删除加载bean过程中所记录的各种辅助状态 同一个类中
protected void addSingleton(String beanName, Object singletonObject) {
synchronized (this.singletonObjects) {
this.singletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.add(beanName);
}
}
(7)返回处理结果
虽然我们了解了加载bean的逻辑架构,但是现在我们并没有开始对bean加载功能进行探索,之前提到过,bean的加载逻辑实在传入的ObjectFactory类型的参数
sharedInstance = getSingleton(beanName, () -> {
try {
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
// Explicitly remove instance from singleton cache: It might have been put there
// eagerly by the creation process, to allow for circular reference resolution.
// Also remove any beans that received a temporary reference to the bean.
destroySingleton(beanName);
throw ex;
}
});
[](javascript:void(0)😉
ObjectFactory的核心部分只调用了createBean()方法,继续探索createBean()
5.实例化bean
- 实例化:指创建类实例(对象)的过程。比如使用构造方法new对象,为对象在内存中分配空间。(要创建对象,但是并未生成对象)
- 初始化:指为类中各个类成员(被static修饰的成员变量)赋初始值的过程,是类生命周期中的一个阶段。简单理解为对象中的属性赋值的过程。(对象已经生成,为其属性赋值)
5.0流程图
/**
* Central method of this class: creates a bean instance,
* populates the bean instance, applies post-processors, etc.
* @see #doCreateBean
*/
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
RootBeanDefinition mbdToUse = mbd;
// 锁定class,根据设置的class属性或者根据beanName来解析Class,具体在实现逻辑在resolveBeanClass()方法中
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
// Prepare method overrides.
// 验证及准备覆盖方法
try {
//
mbdToUse.prepareMethodOverrides();
}
try {
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
// 给BeanPostProcessors一个机会来返回代理来替代真正的实例
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
}
try {
// 真正的创建bean的代码在这个方法中
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isDebugEnabled()) {
logger.debug("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
}
[](javascript:void(0)😉
来看下具体步骤和功能
(1)根据设置的class属性或者是beanName来解析Class
(2)对override属性进行标记和验证
这个其实spring中没有override-method这样的配置,但是spring是存在lookup-method和replace-method的,而这两个配置的加载其实
就是将配置统一存放到BeanDefinition中的methodOverride属性里,这个函数的操作其实就是针对这两个属性
(3)应用初始化前的后处理器,解析指定bean是否存在初始化前的短路操作
(4)创建bean
5.1 处理override属性
prepareMethodOverrides()方法在org.springframework.beans.factory.support包下的AbstractBeanDefinition类中
public void prepareMethodOverrides() throws BeanDefinitionValidationException {
if (this.hasMethodOverrides()) {
this.getMethodOverrides().getOverrides().forEach(this::prepareMethodOverride);
}
}
//继续看prepareMethodOverride(mo)方法的源码,在同一个类中:
protected void prepareMethodOverride(MethodOverride mo) {
int count = ClassUtils.getMethodCountForName(this.getBeanClass(), mo.getMethodName());
if (count == 0) {
throw new BeanDefinitionValidationException("Invalid method override: no method with name '" + mo.getMethodName() + "' on class [" + this.getBeanClassName() + "]");
} else {
if (count == 1) {
mo.setOverloaded(false);
}
}
}
spring是存在lookup-method和replace-method的,而这两个配置的加载其实就是将配置统一存放到BeanDefinition中的methodOverride属性里,
这两个方法的实现原理是在bean实例化的时候检测到存在MethodOverride,会动态的为当前bean生成动态代理并使用对应的拦截器为bean做增强处理,
相关逻辑实现在bean的实例化部分详细及讲解
但是,对于方法的匹配来讲,如果一个类中存在若干个重载方法,那么,在函数调用及增强的时候,还需要根据参数类型进行匹配,来最终确认当前调用的是
哪个函数。但是,spring将一部分匹配工作在这里完成了,如果当前类中的方法只有一个,那么就设置重载方法没有重载,这样在后续调用的时候便可以直接
使用找到的方法,而不需要进行方法的参数匹配验证了,而且还可以提前对方法存在性进行验证。
5.2 实例化的前置处理
- https://blog.csdn.net/xuan_lu/article/details/106061931
- InstantiationAwareBeanPostProcessor
该接口继承自BeanPostProcessor接口,并自定义如图方法。
- postProcessBeforeInstantiation 实例化前置处理 (对象未生成)
- postProcessAfterInstantiation 实例化后置处理 (对象已经生成)
- postProcessPropertyValues 修改属性值。(对象已经生成)
- BeanPostProcessor
- postProcessBeforeInitialization初始化前置处理 (对象已经生成)
- postProcessAfterInitialization初始化后置处理 (对象已经生成)
在真正调用doCreat方法创建bean之前调用了一个代理的方法,resolveBeforeInstantiation(beanName, mbdToUse),对BeanDefinition中属性做了前置处理,
当前置处理返回的结果如果不为空,那么直接略过后续的bean的创建而直接返回结果,这一特性虽然很容易被忽略,但是起着至关重要的作用,我们熟悉的AOP功能
就是在这里判断的
org.springframework.beans.factory.support包下AbstractAutowireCapableBeanFactory类中resolveBeforeInstantiation方法
[](javascript:void(0)😉
@Nullable
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
Object bean = null;
// 如果尚未被解析
if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
// Make sure bean class is actually resolved at this point.
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
Class<?> targetType = determineTargetType(beanName, mbd);
if (targetType != null) {
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
if (bean != null) {
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
}
mbd.beforeInstantiationResolved = (bean != null);
}
return bean;
}
[](javascript:void(0)😉
此方法中判断了该bean是否有InstantiationAwareBeanPostProcessors(),如果有,
就调用applyBeanPostProcessorsBeforeInstantiation和applyBeanPostProcessorsAfterInitialization进行处理
该方法若能返回结果,则直接跳过了createBean的流程
(1)实例化前的后处理应用
bean的实例化前调用,也就是将AbstractBeanDefinition转换为BeanWrapper前处理,给子类一个修改BeanDefinition的机会,也就是说,bean通过这个方法处理之后
可能不是我们之前的bean了
[](javascript:void(0)😉
@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;
}
(2)实例化后的后处理应用
在讲解从缓存中获取单例bean的时候提过,spring中的规则是在bean的初始化后尽可能保证将注册的后处理器postProcessAfterInitialization方法应用到bean中,
因为如果返回的bean不为空,那么便不会再次经历普通bean的创建过程,所以只能在这里应用后处理器的postProcessAfterInitialization方法
[](javascript:void(0)😉
@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;
}
6 doCreateBean
0.流程图
(1)如果是单例,则需要首先清除缓存
(2)实例化bean,将BeanDefinition转换成BeanWrapper,转化是一个复杂过程,大致思路如下
1.如果存在工厂方法则使用工厂方法进行初始化
2.一个类有多个构造函数,每个构造函数都有不同的参数,所以需要根据参数锁定构造函数并进行初始化
3.如果即不存在工厂方法,也没有指定构造方法,则使用指定的构造方法初始化bean
(3)MergedBeanDefinitionPostProcessors的应用
bean合并后处理,autowire注解正是通过此方法实现注入类型的预解析
(4)依赖处理
(5)属性填充。将所有属性填充到bean的实例中
(6)循环依赖检查
之前提到过,在spring中解决循环依赖只对单例有效,而对于prototype的bean,spring没有更好的解决办法,唯一要做的是抛出异常。
(7)注册DisposableBean
如果配置了destroy-method,这里需要注册以便于在销毁时候调用
(8)完成创建并返回
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
// Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
// 根据指定bean使用对应的策略创建新的实例,如:工厂方法、构造函数自动注入、简单初始化
if (instanceWrapper == null) {
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
final Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
// Allow post-processors to modify the merged bean definition.
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
// 应用MergedBeanDefinitionPostProcessors
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing of merged bean definition failed", ex);
}
mbd.postProcessed = true;
}
}
// Eagerly cache singletons to be able to resolve circular references
// even when triggered by lifecycle interfaces like BeanFactoryAware.
// 是否需要提早曝光:单例&允许循环依赖&当前bean正在创建中,检测循环依赖
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isDebugEnabled()) {
logger.debug("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
//为避免后期循环依赖,可以在bean初始化完成前将创建实例的ObjectFactory加入工厂
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
// Initialize the bean instance.
Object exposedObject = bean;
try {
// 对bean进行填充,将各个属性值注入,其中,可能存在依赖于其他bean的属性,则会递归初始依赖bean
populateBean(beanName, mbd, instanceWrapper);
// 初始化bean
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
catch (Throwable ex) {
if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
throw (BeanCreationException) ex;
}
else {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
}
}
if (earlySingletonExposure) {
Object earlySingletonReference = getSingleton(beanName, false);
// earlySingletonReference只有在检测到有循环依赖的情况下才会不为空
if (earlySingletonReference != null) {
// 如果exposedObject没有在初始化方法中被改变,也就是没有被增强
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
}
else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
String[] dependentBeans = getDependentBeans(beanName);
Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
for (String dependentBean : dependentBeans) {
// 检测依赖
if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
actualDependentBeans.add(dependentBean);
}
}
// 因为bean创建后其所依赖的bean一定已经创建的
// actualDependentBeans不为空则表示当前bean创建后其依赖的bean却没有被全部创建完,存在循环依赖
if (!actualDependentBeans.isEmpty()) {
throw new BeanCurrentlyInCreationException(beanName,
"Bean with name '" + beanName + "' has been injected into other beans [" +
StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
"] in its raw version as part of a circular reference, but has eventually been " +
"wrapped. This means that said other beans do not use the final version of the " +
"bean. This is often the result of over-eager type matching - consider using " +
"'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
}
}
}
}
// Register bean as disposable.
try {
// 根据scope注册bean
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
}
1 创建bean实例
首先从createBeanInstance()方法开始,这个方法在org.springframework.beans.factory.support包下AbstractAutowireCapableBeanFactory类下
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
// Make sure bean class is actually resolved at this point.
// 解析Class
Class<?> beanClass = resolveBeanClass(mbd, beanName);
if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
}
Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
if (instanceSupplier != null) {
return obtainFromSupplier(instanceSupplier, beanName);
}
// 如果工厂方法不为空则使用工厂方法初始化策略
if (mbd.getFactoryMethodName() != null) {
return instantiateUsingFactoryMethod(beanName, mbd, args);
}
// Shortcut when re-creating the same bean...
boolean resolved = false;
boolean autowireNecessary = false;
if (args == null) {
synchronized (mbd.constructorArgumentLock) {
// 一个类有多个构造函数,每个构造函数都有不同的参数,所以调用钱需要先根据参数锁定构造函数或者是工厂方法
if (mbd.resolvedConstructorOrFactoryMethod != null) {
resolved = true;
autowireNecessary = mbd.constructorArgumentsResolved;
}
}
}
// 如果已经解析过则使用解析好的构造函数不需要再次锁定
if (resolved) {
if (autowireNecessary) {
// 构造函数自动注入
return autowireConstructor(beanName, mbd, null, null);
}
else {
// 使用默认的构造函数
return instantiateBean(beanName, mbd);
}
}
// Candidate constructors for autowiring?
// 需要根据参数解析构造函数
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
// 构造函数自动注入
return autowireConstructor(beanName, mbd, ctors, args);
}
// No special handling: simply use no-arg constructor.
// 使用默认构造函数构造
return instantiateBean(beanName, mbd);
}
[](javascript:void(0)😉
大致梳理一下这个createBeanInstance()方法中的思路:
(1)如果在RootBeanDefinition中存在factoryMethodName属性,或者说是在配置文件中配置了factory-method,那么spring会尝试使用
instantiateUsingFactoryMethod(beanName, mbd, args)方法根据RootBeanDefiniton中配置生成bean的实例
(2)解析构造函数并进行构造函数的实例化,因为一个bean对应的类中可能会有多个构造函数,而每个构造函数的参数不同,spring会根据参数以及类型
去判断最终会使用哪个构造函数进行实例化。但是,判断过程是比较消耗性能的,所以采用缓存机制,如果已经解析过了,则不需要重复解析,而是直接从
RootBeanDefinition中的属性resolvedConstructorOrFactoryMethod缓存的值去取,否则需要再次解析,并将结果添加至RootBeanDefinition中的属性resolvedConstructorOrFactoryMethod中
2记录创建bean的ObjectFactory
[[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-f6txzD4w-1604735670476)(D:\Typora\java核心\A源码专题\spring\assets\copycode-1603891632091.gif)]](javascript:void(0)😉
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isDebugEnabled()) {
logger.debug("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
//为避免后期循环依赖,可以在bean初始化完成前将创建实例的ObjectFactory加入工厂
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
synchronized(this.singletonObjects) {
if (!this.singletonObjects.containsKey(beanName)) {
this.singletonFactories.put(beanName, singletonFactory);
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.add(beanName);
}
}
}
[](javascript:void(0)😉
这一个小内容是来解释spring中处理依赖的方法的
(1)earlySingletonExposure,字面意思是提早曝光,哪些条件可以影响这个值呢?
(2)mbd.isSingleton():此RootBeanDefinition代表的是是否是单例
(3)this.allowCircularReferences:是否允许循环依赖
(4)isSingletonCurrentlyInCreation(beanName):该bean是否在创建中
3.依赖注入
属性注入的功能,主要是使用的populateBean()方法,看一下属性是如何注入
org.springframework.beans.factory.support包下的AbstractAutowireCapableBeanFactory类中
在这个处理方法中populateBean,主要处理流程是这样的:
(1)InstantiationAwareBeanPostProcessor处理器的postProcessAfterInstantiation来控制是否进行属性的填充
(2)根据注入类型(byName/byType),提取依赖的bean,并统一存入PropertyValues
(3)应用InstantiationAwareBeanPostProcessor处理器的postProcessPropertyValues方法,对属性获取完毕填充前对属性再次处理,典型应用是
org.springframework.beans.factory.annotation包下的RequiredAnnotationBeanPostProcessor
(4)将所有的PropertyValues中的属性填充至BeanWrapper中
[[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-m7HAIhIC-1604735670478)(D:\Typora\java核心\A源码专题\spring\assets\copycode-1603891755779.gif)]](javascript:void(0)😉
/**
* Populate the bean instance in the given BeanWrapper with the property values
* from the bean definition.
* @param beanName the name of the bean
* @param mbd the bean definition for the bean
* @param bw the BeanWrapper with bean instance
*/
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
if (bw == null) {
if (mbd.hasPropertyValues()) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
}
else {
// Skip property population phase for null instance.
// 没有可以填充的属性
return;
}
}
// Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
// state of the bean before properties are set. This can be used, for example,
// to support styles of field injection.
// 给InstantiationAwareBeanPostProcessors最后一次机会在属性设置前改变bean
// 例如:可以用来支撑属性注入的类型
boolean continueWithPropertyPopulation = true;
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
// 返回值是否继续填充bean
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
continueWithPropertyPopulation = false;
break;
}
}
}
}
// 如果后处理器发出停止填充命令则终止后续的执行
if (!continueWithPropertyPopulation) {
return;
}
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME || mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) {
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
// Add property values based on autowire by name if applicable.
// 根据名称自动注入
if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
// Add property values based on autowire by type if applicable.
// 根据类型自动注入
if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}
// 后处理器已经初始化
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
// 需要依赖检查
boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);
if (hasInstAwareBpps || needsDepCheck) {
if (pvs == null) {
pvs = mbd.getPropertyValues();
}
PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
if (hasInstAwareBpps) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
// 对所有需要依赖的属性进行后处理
pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvs == null) {
return;
}
}
}
}
if (needsDepCheck) {
// 依赖检查,对应depend-on属性 spring3.0废弃
checkDependencies(beanName, mbd, filteredPds, pvs);
}
}
if (pvs != null) {
// 将属性应用到bean中
applyPropertyValues(beanName, mbd, bw, pvs);
}
}
[](javascript:void(0)😉
其中的有几个方法来看一下源码:
1、根据名称依赖注入 autowireByName
org.springframework.beans.factory.support包下的AbstractAutowireCapableBeanFactory类中
[](javascript:void(0)😉
/**
* Fill in any missing property values with references to
* other beans in this factory if autowire is set to "byName".
* @param beanName the name of the bean we're wiring up.
* Useful for debugging messages; not used functionally.
* @param mbd bean definition to update through autowiring
* @param bw the BeanWrapper from which we can obtain information about the bean
* @param pvs the PropertyValues to register wired objects with
*/
protected void autowireByName(
String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
// 在bw中寻找需要依赖注入的属性
String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
for (String propertyName : propertyNames) {
if (containsBean(propertyName)) {
// 递归初始化相关的bean
Object bean = getBean(propertyName);
pvs.add(propertyName, bean);
// 注册依赖
registerDependentBean(propertyName, beanName);
if (logger.isDebugEnabled()) {
logger.debug("Added autowiring by name from bean name '" + beanName +
"' via property '" + propertyName + "' to bean named '" + propertyName + "'");
}
}
else {
if (logger.isTraceEnabled()) {
logger.trace("Not autowiring property '" + propertyName + "' of bean '" + beanName +
"' by name: no matching bean found");
}
}
}
}
[](javascript:void(0)😉
如果之前了解过autowire的使用方法,我也没有理解清楚这段代码,传入的参数pvs中找到已经加载的bean,并且递归实例化,进而加入到pvs中
2、根据类型自动注入 autowireByType
3、applyPropertyValues
程序运行到这里,已经完成了对所有注入属性的获取,但是获取的属性是以PropertyValues形式存在的,还并没有应用到已经实例化的bean中,这一工作在
applyPropertyValues函数中实现,org.springframework.beans.factory.support包下的AbstractAutowireCapableBeanFactory类中
[](javascript:void(0)😉
/**
* Apply the given property values, resolving any runtime references
* to other beans in this bean factory. Must use deep copy, so we
* don't permanently modify this property.
* @param beanName the bean name passed for better exception information
* @param mbd the merged bean definition
* @param bw the BeanWrapper wrapping the target object
* @param pvs the new property values
*/
protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
if (pvs.isEmpty()) {
return;
}
// 系统验证
if (System.getSecurityManager() != null && bw instanceof BeanWrapperImpl) {
((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext());
}
MutablePropertyValues mpvs = null;
List<PropertyValue> original;
if (pvs instanceof MutablePropertyValues) {
mpvs = (MutablePropertyValues) pvs;
// 如果mpvs中的值已经被转换为对应的类型,那么可以直接设置到BeanWrapper中
if (mpvs.isConverted()) {
// Shortcut: use the pre-converted values as-is.
try {
bw.setPropertyValues(mpvs);
return;
}
catch (BeansException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Error setting property values", ex);
}
}
original = mpvs.getPropertyValueList();
}
else {
// 如果pvs并不使用MutablePropertyValues封装的类型,那么直接使用原始的属性获取方法
original = Arrays.asList(pvs.getPropertyValues());
}
TypeConverter converter = getCustomTypeConverter();
if (converter == null) {
converter = bw;
}
// 获取对应的解析器
BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter);
// Create a deep copy, resolving any references for values.
List<PropertyValue> deepCopy = new ArrayList<>(original.size());
boolean resolveNecessary = false;
// 遍历属性,将属性转换为对应类的对应属性类型
for (PropertyValue pv : original) {
if (pv.isConverted()) {
deepCopy.add(pv);
}
else {
String propertyName = pv.getName();
Object originalValue = pv.getValue();
Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);
Object convertedValue = resolvedValue;
boolean convertible = bw.isWritableProperty(propertyName) &&
!PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName);
if (convertible) {
convertedValue = convertForProperty(resolvedValue, propertyName, bw, converter);
}
// Possibly store converted value in merged bean definition,
// in order to avoid re-conversion for every created bean instance.
if (resolvedValue == originalValue) {
if (convertible) {
pv.setConvertedValue(convertedValue);
}
deepCopy.add(pv);
}
else if (convertible && originalValue instanceof TypedStringValue &&
!((TypedStringValue) originalValue).isDynamic() &&
!(convertedValue instanceof Collection || ObjectUtils.isArray(convertedValue))) {
pv.setConvertedValue(convertedValue);
deepCopy.add(pv);
}
else {
resolveNecessary = true;
deepCopy.add(new PropertyValue(pv, convertedValue));
}
}
}
if (mpvs != null && !resolveNecessary) {
mpvs.setConverted();
}
// Set our (possibly massaged) deep copy.
try {
// BeanWrapper中 wrapper的意思是包装纸的意思 这里大概就是bean的封装类
bw.setPropertyValues(new MutablePropertyValues(deepCopy));
}
catch (BeansException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Error setting property values", ex);
}
}
[[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cgSx9jtK-1604735670483)(D:\Typora\java核心\A源码专题\spring\assets\copycode-1603891755779.gif)]](javascript:void(0)😉
4.初始化bean
(0)流程图
doCreateBean函数中有这样一行代码:这行代码中initializeBean函数就是初始化bean的逻辑
exposedObject = initializeBean(beanName, exposedObject, mbd);
这个方法在org.springframework.beans.factory.support包下AbstractAutowireCapableBeanFactory类下
[[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4x7yLwN0-1604735670485)(D:\Typora\java核心\A源码专题\spring\assets\copycode-1603892753866.gif)]](javascript:void(0)😉
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {
// 对特殊的bean处理:Aware、BeanClassLoader、BeanFactoryAware
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
// 应用后处理器
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
// 激活用户自定义的init方法
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
if (mbd == null || !mbd.isSynthetic()) {
// 后处理器应用
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
[[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XiuY5S84-1604735670485)(D:\Typora\java核心\A源码专题\spring\assets\copycode-1603892753866.gif)]](javascript:void(0)😉
虽说此函数的目的主要是进行客户设定的初始化方法的调用,但是除此之外还有其他必要的工作
(1)激活Aware方法
理解一下Aware的使用,spring中提供了一些Aware接口,比如好多org.springframework.beans.factory,这个包下好多啊,实现这些Aware接口的bean被初始化之后
可以取得一些相应的资源,例如,实现BeanFactoryAware的bean在初始化后,spring容器会注入BeanFactory的实例,来看一下Aware的使用
[](javascript:void(0)😉
// 定义普通的bean
public class Hello{
public void say(){
System.out.println("hello");
}
}
// 定义BeanFactoryAware类型的bean
public class Test implements BeanFactoryAware {
private BeanFactory beanFactory;
// 声明bean的时候spring会自动注入BeanFactory
@override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
this.beanFactory = beanFactory;
}
public void testAware(){
Hello hello = (Hello) beanFactory.getBean("hello");
hello.say();
}
}
[](javascript:void(0)😉
基本上就是这样使用的,看一下 源码:
这个方法在org.springframework.beans.factory.support包下AbstractAutowireCapableBeanFactory类下
[](javascript:void(0)😉
1 private void invokeAwareMethods(final String beanName, final Object bean) {
2 if (bean instanceof Aware) {
3 if (bean instanceof BeanNameAware) {
4 ((BeanNameAware) bean).setBeanName(beanName);
5 }
6 if (bean instanceof BeanClassLoaderAware) {
7 ClassLoader bcl = getBeanClassLoader();
8 if (bcl != null) {
9 ((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
10 }
11 }
12 if (bean instanceof BeanFactoryAware) {
13 ((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
14 }
15 }
16 }
[](javascript:void(0)😉
(2)处理器的应用
BeanPostProcessor是spring开放式架构中必不可少的亮点,给用户充足的权限去更改或者扩展spring,除了BeanPostProcessor,还有很多PostProcessor,
当然大部分都是以此为基础,继承组BeanPostProcessor,BeanPostProcessor的使用位置就是这里,在调用客户自定义初始方法前以及调用自定义初始方法后
分别会调用BeanPostProcessor的postProcessBeforeInitialization和postProcessAfterInitialization,使用户根据自己的需求进行自己处理
这个方法在org.springframework.beans.factory.support包下AbstractAutowireCapableBeanFactory类下
[](javascript:void(0)😉
@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;
}
@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;
}
[[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GsFxeLjf-1604735670492)(D:\Typora\java核心\A源码专题\spring\assets\copycode-1603892753866.gif)]](javascript:void(0)😉
(3)激活自定义的init方法
客户定制的初始化方法除了我们熟知的使用init-method配置外,还要使用自定义bean实现initializeBean接口,并在afterPropertiesSet中实现自己的初始化逻辑
init-method与afterPropertiesSet都是在初始化bean时执行,指定顺序是afterPropertiesSet先执行,init-method再执行
在invokeInitMethods方法中实现了这部分处理逻辑
[](javascript:void(0)😉
protected void invokeInitMethods(String beanName, final Object bean, @Nullable RootBeanDefinition mbd)
throws Throwable {
// 首先检查是否是InitializingBean,如果是的话就调用afterPropertiesSet()
boolean isInitializingBean = (bean instanceof InitializingBean);
if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
if (logger.isDebugEnabled()) {
logger.debug("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
}
if (System.getSecurityManager() != null) {
try {
AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
((InitializingBean) bean).afterPropertiesSet();
return null;
}, getAccessControlContext());
}
catch (PrivilegedActionException pae) {
throw pae.getException();
}
}
else {
((InitializingBean) bean).afterPropertiesSet();
}
}
if (mbd != null && bean.getClass() != NullBean.class) {
String initMethodName = mbd.getInitMethodName();
if (StringUtils.hasLength(initMethodName) &&
!(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
!mbd.isExternallyManagedInitMethod(initMethodName)) {
// 调用自定义初始化方法
invokeCustomInitMethod(beanName, bean, mbd);
}
}
}
[](javascript:void(0)😉
5 注册DisposableBean
spring中不但提供了对于初始化方法的扩展入口,同样也提供了销毁的扩展入口,对于销毁方法的扩展,除了我们熟知的配置属性destroy-method方法,用户还
可以注册后处理器DestructionAwareBeanPostProcessor来统一处理bean的销毁方法
[](javascript:void(0)😉
protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) {
AccessControlContext acc = (System.getSecurityManager() != null ? getAccessControlContext() : null);
if (!mbd.isPrototype() && requiresDestruction(bean, mbd)) {
if (mbd.isSingleton()) {
// Register a DisposableBean implementation that performs all destruction
// work for the given bean: DestructionAwareBeanPostProcessors,
// DisposableBean interface, custom destroy method.
// 单例模式下注册需要销毁的bean,此方法中会处理实现DisposableBean的bean,
// 并且对所有的bean使用DestructionAwareBeanPostProcessor处理DisposableBean
registerDisposableBean(beanName,
new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
}
else {
// A bean with a custom scope...
// 自定义scope处理
Scope scope = this.scopes.get(mbd.getScope());
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope name '" + mbd.getScope() + "'");
}
scope.registerDestructionCallback(beanName,
new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
}
}
}
[](javascript:void(0)😉