Spring-bean的加载
经过前面的解析,我们已经完成了对XML配置文件的解析,接下来将会是更大的挑战,对bean加载的解析。bean加载的功能实现远比bean的解析要复杂的多。同样,我们还是以测试调用代码为例:
@Test
public void test1(){
XmlBeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("spring.xml"));
//加载bean实例
MyBeanTest myBeanTest = (MyBeanTest) beanFactory.getBean("myBeanTest");
System.out.println(myBeanTest.getTestStr());
}
@Override
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}
protected <T> T doGetBean(
String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
throws BeansException {
//提取对应的beanName
String beanName = transformedBeanName(name);
Object beanInstance;
/**
* 检查缓存中或者实例工厂中是否有对应的实例
* 为什么首先会使用这段代码呢
* 因为在创建单例bean的时候会存在依赖注入的情况,而在创建依赖的时候为了避免循环依赖,
* Spring创建bean的原则是不等bean创建完成就会将创建bean的ObjectFactory提前曝光
* 也就是将ObjectFactory加入缓存中,一旦下个bean创建时候需要依赖上个bean则直接使用ObjectFactory;
*/
//直接尝试从缓存获取或者singletonFactories中的ObjectFactory中获取
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
if (logger.isTraceEnabled()) {
if (isSingletonCurrentlyInCreation(beanName)) {
logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +
"' that is not fully initialized yet - a consequence of a circular reference");
}
else {
logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
}
}
//返回对应的实例,有时候存在诸如FactoryBean的情况并不是直接返回实例本身而是返回指定方法返回的实例
beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
else {
/**
* 只有在单例情况下才会尝试解决循环依赖,原型模式情况下,如果存在
* A中有B的属性,B中有A的属性,那么当依赖注入时,就会产生当A还未创建完的时候因为
* 对于B的创建再次返回创建A,造成循环依赖,也就是下面的情况
*/
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
// 如果beanDefinitionMap中也就是在所有已经加载的类中不包含beanName则尝试从parentBeanFactory中检测
BeanFactory parentBeanFactory = getParentBeanFactory();
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
String nameToLookup = originalBeanName(name);
//递归到BeanFactory中寻找
if (parentBeanFactory instanceof AbstractBeanFactory) {
return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
nameToLookup, requiredType, args, typeCheckOnly);
}
else if (args != null) {
return (T) parentBeanFactory.getBean(nameToLookup, args);
}
else if (requiredType != null) {
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
else {
return (T) parentBeanFactory.getBean(nameToLookup);
}
}
//如果不是仅仅做类型检测则是创建bean,这里要进行记录
if (!typeCheckOnly) {
markBeanAsCreated(beanName);
}
StartupStep beanCreation = this.applicationStartup.start("spring.beans.instantiate")
.tag("beanName", name);
try {
if (requiredType != null) {
beanCreation.tag("beanType", requiredType::toString);
}
//将存储XML配置文件的GernericBeanDefinition转化为RootBeanDefinition,如果指定BeanName是子bean的话,会合并父类的相关属性
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);
String[] dependsOn = mbd.getDependsOn();
//如果存在依赖则需要递归实例化依赖的bean
if (dependsOn != null) {
for (String dep : dependsOn) {
if (isDependent(beanName, dep)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
//缓存依赖调用
registerDependentBean(dep, beanName);
try {
getBean(dep);
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
}
}
}
//实例化依赖的bean之后便可以实例化mbd本省了
// 单例模式的创建
if (mbd.isSingleton()) {
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;
}
});
beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
else if (mbd.isPrototype()) {
// 多例模式的创建
Object prototypeInstance = null;
try {
beforePrototypeCreation(beanName);
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
beanInstance = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
else {
//指定的scope模式的创建
String scopeName = mbd.getScope();
if (!StringUtils.hasLength(scopeName)) {
throw new IllegalStateException("No scope name defined for bean ´" + beanName + "'");
}
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, () -> {
beforePrototypeCreation(beanName);
try {
return createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
});
beanInstance = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
}
catch (IllegalStateException ex) {
throw new ScopeNotActiveException(beanName, scopeName, ex);
}
}
}
catch (BeansException ex) {
beanCreation.tag("exception", ex.getClass().toString());
beanCreation.tag("message", String.valueOf(ex.getMessage()));
cleanupAfterBeanCreationFailure(beanName);
throw ex;
}
finally {
beanCreation.end();
}
}
//类型转换
return adaptBeanInstance(name, beanInstance, requiredType);
}
仅从代码量就能看出bean的加载经历了一个相当复杂的过程,其中涉及各种各样复杂的考虑。通过注解,可以了解Spring加载bean的大概流程:
- 转化对应的beanName:这里传入的参数name不一定就是beanName,也有可能是别名,需要一系列的解析。去除FactoryBean的修饰符,也就是如果name=“&aa”,首先会去除&而使name=“aa”;取指定alias所最终代表的beanName;
- 尝试从缓存中加载单例:单例在Spring的同一个容器内只会被创建一次,后续再获取bean,就直接从单例缓存中获取了。当然这里也只是尝试加载,首先尝试从缓存中加载,如果加载不成功则尝试从singletonFactories中加载。因为在创建单例bean的时候,会存在依赖注入的情况,而在创建依赖的时候,为了避免循环依赖,在Spring创建bean的原则是不等bean创建完成就会将创建bean的ObjectFactory提前曝光加入缓存中,一旦下一个bean的创建需要上一个bean则直接使用beanFactory;
- bean的实例化:如果从bean中得到了bean的原始状态,则需要对bean进行实例化。这里有必要强调一下,缓存中记录的只是最原始的bean状态,并不一定是我们最终想要的bean;
- 原型模式的依赖检查:只有在单例模式下才会尝试解决循环依赖,如果存在A中有B的属性,B中有A的属性,那么当依赖注入时,就会产生当A还未创建完的时候因为对于B的创建再次返回创建A,造成循环依赖;
- 检测parentBeanFactory:如果当前加载的xml配置文件中,不包含beanName所对应的配置,就只能到parentBeanFactory去尝试下了,然后再递归的调用getBean方法;
- 将存储XML配置文件的GernericBeanDefinition转化为RootBeanDefinition;
- 寻找依赖:在初始化某一个bean的时候首先会初始化这个bean所对应的依赖;
- 针对不同的scope进行bean的创建;
- 类型转换:通常对该方法调用此参数为空,但可能会存在这样的情况,返回的bean其实是String,但requiredType却传入了Integer类型,这个时候,这个步骤就会起类型转化的作用;
经过上面步骤,整个bean就加载结束了。在细化分析各个步骤提供的功能前,我们有必要先了解一下FactoryBean的用法。
一、FactoryBean的使用
一般情况下,Spring通过反射机制利用bean的class属性指定实现类来实例化bean。但在实例化bean比较复杂的情况下,配置方式受限。Spring为此提供了一个FactoryBean的工厂类接口,用户可以实现该接口定制实例化bean的逻辑;
public interface FactoryBean<T> {
String OBJECT_TYPE_ATTRIBUTE = "factoryBeanObjectType";
@Nullable
T getObject() throws Exception;
@Nullable
Class<?> getObjectType();
default boolean isSingleton() {
return true;
}
}
当Spring实例化 FactoryBean的子类时,Spring就通过调用getObject()的方法返回。如果想获取FactoryBean的实例,则需要在使用getBean(beanName)方法时在beanName前加上“&”的前缀;
二、缓存中获取单例bean
介绍过FactoryBean的用法后,我们就可以了解bean加载的过程了。单例在Spring的同一个容器内只会被创建一次,后续可以直接从单例缓存中获取。
当然这里也只是尝试加载,首先尝试从缓存中加载,然后再次尝试从singletonFactories中加载。因为在创建单例bean的时候会存在依赖注入的情况,而在创建依赖的时候为了避免循环依赖,Spring创建的原则是不等bean创建完成就会将创建bean的ObjectFactory提前曝光加入到缓存中,一旦下一个bean创建时需要依赖上个bean,则直接使用ObjectFactory;
@Override
@Nullable
public Object getSingleton(String beanName) {
return getSingleton(beanName, true);
}
@Nullable
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
// 检查单例缓存中是否存在实例
Object singletonObject = this.singletonObjects.get(beanName);
//如果singletonObjects中不存在,并且正在单例创建中
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
//检查earlySingletonObjects中是否存在
singletonObject = this.earlySingletonObjects.get(beanName);
//如果earlySingletonObjects中不存在,并且允许提前引用(true)
if (singletonObject == null && allowEarlyReference) {
/**
*锁定singletonObjects对象,保证只会调用一次singletonFactory.getObject()
*锁定后操作同上,其实这里的代码逻辑类似于双重检查锁,减少了锁的开销
*/
synchronized (this.singletonObjects) {
// Consistent creation of early reference within full singleton lock
singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null) {
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
singletonObject = singletonFactory.getObject();
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
}
}
return singletonObject;
}
这个方法首先尝试从singletonObjects里面获取实例,如果获取不到再从earlySingletonObjects里面获取,如果还获取不倒,再尝试从singletonFactories里面获取beanName对应的ObjectFactory,然后调用这个ObjectFactory的getObject来创建bean,并放到earlySingletonObjects里面去,并且从singletonObjects里面remove掉这个ObjectFactory。
这里涉及用于存储bean的不同map,简单解释如下:
- singletonObjects:用户保存BeanName和创建的bean实例之间的关系,beanName–>beanInstance;
- singletonFactories:用于保存BeanName和创建bean的工厂之间的关系,beanName–>ObjectFactory;
- earlySingletonObjects:用于保存BeanName和创建bean实例之间的关系,当bean还在创建过程中,就可以通过getBean的方法获取到,目的是用来检查循环引用;
- registerSingletons:用来保存当前所有已注册的bean;
三、从bean的实例中获取对象
在getBean方法中,getObjectForBeanInstance是一个高频使用的方法,无论是从缓存中获取bean还是根据不同的scope策略加载bean。总之,我们在得到bean的实例后要做的第一件事情就是调用这个方法来检测一下正确性,其实就是用于检测当前bean是否是FactoryBean类型的bean,如果是,那么需要调用该bean对应的FactoryBean实例中的getObject()作为返回值;
protected Object getObjectForBeanInstance(
Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {
// 如果beanName以&为前缀,返回FactoryBean类型的实例
if (BeanFactoryUtils.isFactoryDereference(name)) {
if (beanInstance instanceof NullBean) {
return beanInstance;
}
//但实例不是FactoryBean类型,则抛出异常
if (!(beanInstance instanceof FactoryBean)) {
throw new BeanIsNotAFactoryException(beanName, beanInstance.getClass());
}
if (mbd != null) {
mbd.isFactoryBean = true;
}
return beanInstance;
}
//通过上面的代码逻辑,已排除获取FactoryBean类型实例的情况
//这里开始处理获取真是bean实例的情况
//如果不是FactoryBean类型,则该实例即为所求
if (!(beanInstance instanceof FactoryBean)) {
return beanInstance;
}
//如果是FactoryBean类型,则需要走下面的逻辑
Object object = null;
if (mbd != null) {
mbd.isFactoryBean = true;
}
else {
//尝试从factoryBeanObjectCache缓存中获取实例对象
object = getCachedObjectForFactoryBean(beanName);
}
if (object == null) {
// 将实例转化成FactoryBean类型
FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
// 获取bean的定义,如果是子bean会合并父类的相关属性
if (mbd == null && containsBeanDefinition(beanName)) {
mbd = getMergedLocalBeanDefinition(beanName);
}
//判断是用户自定义而非程序本身定义
boolean synthetic = (mbd != null && mbd.isSynthetic());
object = getObjectFromFactoryBean(factory, beanName, !synthetic);
}
return object;
}
protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {
//是否单例,是否有缓存(singletonObjects其实存放的是beanName-->FactoryBean)
if (factory.isSingleton() && containsSingleton(beanName)) {
//锁singletonObjects对象
synchronized (getSingletonMutex()) {
//factoryBeanObjectCache存放的是beanName-->真实的bean
Object object = this.factoryBeanObjectCache.get(beanName);
//如果缓存中没有
if (object == null) {
//调用factoryBean.getObject()方法获取真实的bean
object = doGetObjectFromFactoryBean(factory, beanName);
// Only post-process and store if not put there already during getObject() call above
// (e.g. because of circular reference processing triggered by custom getBean calls)
Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
if (alreadyThere != null) {
object = alreadyThere;
}
else {
if (shouldPostProcess) {
//循环依赖时,判断当前是否在创建该beanName,如果在创建则直接返回引用
if (isSingletonCurrentlyInCreation(beanName)) {
// Temporarily return non-post-processed object, not storing it yet..
return object;
}
//singletonsCurrentlyInCreation添加该beanName
beforeSingletonCreation(beanName);
try {
//调用ObjectFactory的后处理器
object = postProcessObjectFromFactoryBean(object, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(beanName,
"Post-processing of FactoryBean's singleton object failed", ex);
}
finally {
afterSingletonCreation(beanName);
}
}
if (containsSingleton(beanName)) {
this.factoryBeanObjectCache.put(beanName, object);
}
}
}
return object;
}
}
else {
Object object = doGetObjectFromFactoryBean(factory, beanName);
if (shouldPostProcess) {
try {
object = postProcessObjectFromFactoryBean(object, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "Post-processing of FactoryBean's object failed", ex);
}
}
return object;
}
}
private Object doGetObjectFromFactoryBean(FactoryBean<?> factory, String beanName) throws BeanCreationException {
Object object;
try {
if (System.getSecurityManager() != null) {
AccessControlContext acc = getAccessControlContext();
try {
object = AccessController.doPrivileged((PrivilegedExceptionAction<Object>) factory::getObject, acc);
}
catch (PrivilegedActionException pae) {
throw pae.getException();
}
}
else {
//核心逻辑:直接调用getObject方法
object = factory.getObject();
}
}
catch (FactoryBeanNotInitializedException ex) {
throw new BeanCurrentlyInCreationException(beanName, ex.toString());
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "FactoryBean threw exception on object creation", ex);
}
// Do not accept a null value for a FactoryBean that's not fully
// initialized yet: Many FactoryBeans just return null then.
if (object == null) {
if (isSingletonCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(
beanName, "FactoryBean which is currently in creation returned null from getObject");
}
object = new NullBean();
}
return object;
}
对于后处理器的使用我们还未接触,后续章节会使用大量篇幅介绍;这里,我们只需要了解Spring获取bean规则中的一条:尽可能保证所有bean初始化后都会调用注册的BeanPostProcesser的postProcessAfterInitialization方法进行处理。
protected Object postProcessObjectFromFactoryBean(Object object, String beanName) {
return applyBeanPostProcessorsAfterInitialization(object, beanName);
}
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;
}
四、获取单例
之前我们讲解了从缓存中获取单例的过程,那么,如果缓存中不存在已经加载的单例bean就需要从头开始bean的加载过程,而Spring中使用getSingleton的重载方法实现bean的加载过程;
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(beanName, "Bean name must not be null");
//锁singletonObjects对象
synchronized (this.singletonObjects) {
//检查对应的bean是否已经加载过,因为singleton模式本质就是复用已创建的bean
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
if (this.singletonsCurrentlyInDestruction) {
throw new BeanCreationNotAllowedException(beanName,
"Singleton bean creation not allowed while singletons of this factory are in destruction " +
"(Do not request a bean from a BeanFactory in a destroy method implementation!)");
}
if (logger.isDebugEnabled()) {
logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
}
//初始化之前
beforeSingletonCreation(beanName);
boolean newSingleton = false;
boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
if (recordSuppressedExceptions) {
this.suppressedExceptions = new LinkedHashSet<>();
}
try {
//初始化bean
singletonObject = singletonFactory.getObject();
newSingleton = true;
}
catch (IllegalStateException ex) {
// Has the singleton object implicitly appeared in the meantime ->
// if yes, proceed with it since the exception indicates that state.
singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
throw ex;
}
}
catch (BeanCreationException ex) {
if (recordSuppressedExceptions) {
for (Exception suppressedException : this.suppressedExceptions) {
ex.addRelatedCause(suppressedException);
}
}
throw ex;
}
finally {
if (recordSuppressedExceptions) {
this.suppressedExceptions = null;
}
//初始化之后
afterSingletonCreation(beanName);
}
if (newSingleton) {
//加入缓存
addSingleton(beanName, singletonObject);
}
}
return singletonObject;
}
}
上述代码中其实使用了回调方法,使得程序可以在单例创建的前后做一些准备和处理操作,而真正的获取单例bean的方法其实并不在此方法中实现,而是在singletonFactory.getObject()中实现。具体准备和处理操作如下:
①检查缓存是否已经加载过;
②若没有加载,则记录beanName的正在加载状态;
③加载单例前,记录加载状态;
通过beforeSingletonCreation方法,在singletonsCurrentlyInCreation中记录正在创建的bean,这样便可以对循环依赖进行检测;
protected void beforeSingletonCreation(String beanName) {
if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
}
④通过参数传递的ObjectFactory的个体Object方法实例化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");
}
}
⑥将结果记录至缓存并删除加载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);
}
}
⑦返回处理结果;
虽然我们已经从外部了解了加载bean的逻辑结果,但是我们还没有开始对bean加载功能的探索,之前提到过,bean的加载逻辑其实是在传入的ObjectFactory类型的参数singletonFactory中定义,我们反推参数的获取,得到代码:
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;
}
});
五、准备创建bean
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
if (logger.isTraceEnabled()) {
logger.trace("Creating instance of bean '" + beanName + "'");
}
RootBeanDefinition mbdToUse = mbd;
//根据设定的class属性或者className,解析获取class
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
//验证已经准备覆盖的方法
try {
mbdToUse.prepareMethodOverrides();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
beanName, "Validation of method overrides failed", ex);
}
try {
//给BeanPostProcessors一个机会来返回代理替代真正的实例
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
}
catch (Throwable ex) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
"BeanPostProcessor before instantiation of bean failed", ex);
}
try {
//核心逻辑:实例化
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isTraceEnabled()) {
logger.trace("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
// A previously detected exception with proper bean creation context already,
// or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
throw ex;
}
catch (Throwable ex) {
throw new BeanCreationException(
mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
}
}
从上述代码可以总结函数完成的具体步骤和功能:
- 根据设置的class属性或者className来解析class;
- 对override属性进行标记及验证;
- 应用初始化前的后处理器,解析指定bean是否存在初始化前的短路操作;
- 创建bean;
5.1处理override属性
public void prepareMethodOverrides() throws BeanDefinitionValidationException {
// Check that lookup methods exist and determine their overloaded status.
if (hasMethodOverrides()) {
getMethodOverrides().getOverrides().forEach(this::prepareMethodOverride);
}
}
protected void prepareMethodOverride(MethodOverride mo) throws BeanDefinitionValidationException {
//获取对应类中对应方法名的个数
int count = ClassUtils.getMethodCountForName(getBeanClass(), mo.getMethodName());
if (count == 0) {
throw new BeanDefinitionValidationException(
"Invalid method override: no method with name '" + mo.getMethodName() +
"' on class [" + getBeanClassName() + "]");
}
else if (count == 1) {
//标记MethodOverride暂未被覆盖,避免参数类型检查的开销
mo.setOverloaded(false);
}
}
在Spring配置中存在lookup-method和replace-method两个配置功能,而这两个配置的加载其实就是将配置统一存放在BeanDefinition中的methodOverrides属性里。这两个功能的原理其实是在bean实例化的时候如果检测到存在methodOverrides属性,会动态地为当前bean生成代理并使用对应的拦截器为bean做增强处理。
但是,对于方法的匹配,如果一个类中存在若干个重载方法,那么,在函数增强及调用的时候还需要根据参数类型进行匹配,来最终确定当前调用的到底是哪个函数。但是Spring将一部分工作完成了,如果当前类中方法只有一个,那么就设置该方法没有被重载,这样在后续调用的时候可以直接找到方法,而不需要进行参数匹配。
5.2实例化的前置处理
在真正调用doCreate方法创建bean的实例前使用了这样一个方法resolveBeforeInstantiation对beanDefinigiton中的属性做些前置处理。当然,无论其中是否有相应的逻辑实现我们都可以理解,因为真正逻辑实现前后留有处理函数也是可扩展的一种体现。
但是,这并不是最重要的,在函数中还提供了一个短路判断,这才是最关键的部分。
if (bean != null) {
return bean;
}
当经过前置处理后的结果如果不为空,那么会直接略过后续bean的创建而直接返回结果。这一特性虽然很容易被忽略,但是却起着至关重要的作用,我们熟悉的aop就是基于这里判断的。
@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;
}
此方法中最吸引我们的无疑是两个方法,applyBeanPostProcessorsBeforeInstantiation以及applyBeanPostProcessorsAfterInitialization。两个方法实现的非常简单,无非是对后处理器中的所有InstantiationAwareBeanPostProcessor类型的后处理器进行postProcessBeforeInstantiation方法和BeanPostProcessor的postProcessAfterInitialization方法的调用。
a、实例化前的后处理器应用
bean的实例化前调用,也就是将AbstractBeanDefinition转化为BeanWrapper前的处理。给子类一个修改BeanDefinition的机会,也就是说当程序经过这个方法后,bean可能已经不是我们认为的bean了,而是或许成为了一个经过处理的代理bean,可能是通过cglib生成的,也可能是通过其他技术生成的。
@Nullable
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
Object result = bp.postProcessBeforeInstantiation(beanClass, beanName);
if (result != null) {
return result;
}
}
return null;
}
b、实例化后的后处理器应用
在讲解从缓存中获取单例bean的时候就提到过,Spring中的规则是在bean的初始化后尽可能保证将注册的后处理器的postProcessAfterInitialization方法应用到该bean中,因为如果返回的bean不为空,那么便不会再次经历普通bean的创建过程,所以只能在这里应用后处理器的postProcessAfterInitialization方法。
@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.1什么是循环依赖
循环依赖就是循环引用,就是两个或多个bean相互之间的持有对方。
循环调用是无法解决的,除非有终结条件,否则就是死循环,最终导致内存溢出。
6.2Spring如何解决循环依赖
Spring容器循环依赖包括构造器循环依赖和setter循环依赖,那Spring如何解决循环依赖呢。
在Spring中将循环依赖的处理分成了3种情况。
a、构造器循环依赖
表示通过构造器注入构成的循环依赖,此依赖是无法解决的,只能抛出BeanCurrentlyInCreationException异常表示循环依赖。
b、setter循环依赖
表示通过setter注入方式构成的循环依赖。对于setter注入造成的依赖是通过Spring容器提前暴露刚完成构造器注入但未完成其他步骤(如setter注入)的bean来完成的,而且只能解决单例作用域的bean循环依赖。通过提前暴露一个单例工厂方法,从而使其他bean能引用到该bean。
protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(singletonFactory, "Singleton factory must not be null");
synchronized (this.singletonObjects) {
if (!this.singletonObjects.containsKey(beanName)) {
this.singletonFactories.put(beanName, singletonFactory);
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.add(beanName);
}
}
}
c、prototype范围的依赖处理
对于prototype作用域bean,Spring容器无法完成依赖注入,因为Spring容器不进行缓存”prototype“作用域的bean,因此无法提前暴露一个创建中的bean。
七、创建bean
介绍了循环依赖以及Spring中的循环依赖的处理方式后。当经历过resolveBeforeInstantiation方法后,程序有两个选择,如果创建了代理或者说重写了resolveBeforeInstantiation的postProcessBeforeInstantiation方法并在方法中改变了bean,则直接返回就可以,否则需要进行常规bean的创建。而这个常规bean的创建是在doCreateBean中完成的。
ps:ObjectFactory是一个接口,定义了getObject方法。在获取bean的getSingleton方法中,实现的是createBean方法,而在singletonFactories的缓存中,实现的是getEarlyBeanReference方法。可以理解为这个接口就是为了获取bean对象的,至于实现是通过创建还是缓存,就根据你的实现来决定了(匿名内部类)。
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
// Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
//根据指定bean使用对应的策略创建新的实例,如:工厂方法、构造函数自动注入、简单初始化
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
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;
}
}
//是否需要提早曝光:单例&允许循环依赖&当前bean正在创建中,检查循环依赖
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isTraceEnabled()) {
logger.trace("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
//为避免后期循环依赖,可以在bean初始化完成前将创建实例的ObjectFactory加入工厂
//对bean再一次依赖引用,主要应用smartInstantiationAware BeanPostProcessor
//其中我们熟知的aop就是在这里将advice动态的织入bean中,若没有则直接返回bean,不做任何处理
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
// Initialize the bean instance.
Object exposedObject = bean;
try {
//对bean进行填充,将各个属性值注入,其中,可能存在依赖于其他bean的属性,则会递归初始化依赖bean
populateBean(beanName, mbd, instanceWrapper);
//调用初始化方法,比如init—method
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.isEmpty()表明依赖的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 " +
"'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.");
}
}
}
}
// Register bean as disposable.
try {
//根据scopes注册bean
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
}
梳理整个函数的概要思路:
- 如果是单例则需要首先清除缓存;
- 实例化bean,将beanDefinition转换为BeanWrapper。转换是一个复杂的过程,但是我们可以尝试概括大致的功能,如下所示,①如果存在工厂方法则使用工厂方法进行初始化;②一个类有多个构造函数,每个函数都有不同的参数,所以需要根据参数锁定构造函数并初始化;③如果既不存在工厂方法也不存在带有参数的构造方法,则使用默认的构造函数进行bean的实例化;
- MergedBeanDefinitionPostProcessors的应用。bean合并后的处理,Autowired注解正是通过此方法实现诸如类型的预解析;
- 依赖处理。在Spring中会有循环依赖的情况,例如A有B的属性,B有A的属性就会构成一个循环依赖,此时如果A和B都是单例,那么在Spring中的处理方式就是当创建B的时候,涉及注入A的步骤,并不是直接去创建A,而是通过放入缓存中的ObjectFactory来创建实例,这样就解决了循环依赖的问题;
- 属性填充。将所有属性填充至bean实例中;
- 循环依赖检查;
- 注册DisposableBean;
- 完成创建并返回;
7.1创建bean的实例
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
//解析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);
}
}
//需要根据参数解析构造函数
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
//构造函数自动注入
return autowireConstructor(beanName, mbd, ctors, args);
}
// Preferred constructors for default construction?
ctors = mbd.getPreferredConstructors();
if (ctors != null) {
return autowireConstructor(beanName, mbd, ctors, null);
}
//使用默认构造函数构造
return instantiateBean(beanName, mbd);
}
虽然代码中实例化的细节非常复杂,但是在createBeanInstance方法中我们还是可以清晰地看到实例化的逻辑。
- 如果在RootBeanDefinition中存在factoryMethodName属性,或者说在配置文件中配置了factory-method,那么Spring会尝试使用instantiateUsingFactoryMethod方法根据RootBeanDefinition中的配置生产bean的实例;
- 解析构造函数并进行构造函数的实例化。因为一个bean对应的类中可能会有多个构造函数,而每个构造函数的参数不同,Spring在根据参数及类型去判断最终会使用哪个构造函数进行实例化。但是,判断过程是个比较消耗性能的步骤,所以采用缓存机制,如果已经解析过则不需要重复解析而是直接从RootBeanDefinition的resolvedConstructorOrFactoryMethod缓存的值去取,否则需要再次解析;
a、autowireConstructor
对于实例的创建Spring中分为两种情况,一种是通用的实例化,另一种是带有参数的实例化。带有参数的实例化过程相当复杂,因为存在不确定性,所以在判断对应参数上做了大量工作。
protected BeanWrapper autowireConstructor(
String beanName, RootBeanDefinition mbd, @Nullable Constructor<?>[] ctors, @Nullable Object[] explicitArgs) {
return new ConstructorResolver(this).autowireConstructor(beanName, mbd, ctors, explicitArgs);
}
public BeanWrapper autowireConstructor(String beanName, RootBeanDefinition mbd,
@Nullable Constructor<?>[] chosenCtors, @Nullable Object[] explicitArgs) {
BeanWrapperImpl bw = new BeanWrapperImpl();
this.beanFactory.initBeanWrapper(bw);
Constructor<?> constructorToUse = null;
ArgumentsHolder argsHolderToUse = null;
Object[] argsToUse = null;
//explicitArgs通过getBean方法传入,如果getBean方法调用时指定了方法参数那么直接使用
if (explicitArgs != null) {
argsToUse = explicitArgs;
}
else {
//如果在getBean方法时候没有指定,则尝试从配置文件中解析
Object[] argsToResolve = null;
//尝试从缓存中获取
synchronized (mbd.constructorArgumentLock) {
constructorToUse = (Constructor<?>) mbd.resolvedConstructorOrFactoryMethod;
if (constructorToUse != null && mbd.constructorArgumentsResolved) {
//从缓存中取
argsToUse = mbd.resolvedConstructorArguments;
if (argsToUse == null) {
//配置的构造函数参数
argsToResolve = mbd.preparedConstructorArguments;
}
}
}
//如果缓存中存在
if (argsToResolve != null) {
//解析参数类型,如给定方法的构造函数A(int,int)则通过此方法就会把配置中的("1","1")转换为(1,1)
//缓存中的值可能是原始值也可能是最终值
argsToUse = resolvePreparedArguments(beanName, mbd, bw, constructorToUse, argsToResolve);
}
}
//没有被缓存
if (constructorToUse == null || argsToUse == null) {
// Take specified constructors, if any.
Constructor<?>[] candidates = chosenCtors;
if (candidates == null) {
Class<?> beanClass = mbd.getBeanClass();
try {
candidates = (mbd.isNonPublicAccessAllowed() ?
beanClass.getDeclaredConstructors() : beanClass.getConstructors());
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Resolution of declared constructors on bean Class [" + beanClass.getName() +
"] from ClassLoader [" + beanClass.getClassLoader() + "] failed", ex);
}
}
if (candidates.length == 1 && explicitArgs == null && !mbd.hasConstructorArgumentValues()) {
Constructor<?> uniqueCandidate = candidates[0];
if (uniqueCandidate.getParameterCount() == 0) {
synchronized (mbd.constructorArgumentLock) {
mbd.resolvedConstructorOrFactoryMethod = uniqueCandidate;
mbd.constructorArgumentsResolved = true;
mbd.resolvedConstructorArguments = EMPTY_ARGS;
}
bw.setBeanInstance(instantiate(beanName, mbd, uniqueCandidate, EMPTY_ARGS));
return bw;
}
}
// Need to resolve the constructor.
boolean autowiring = (chosenCtors != null ||
mbd.getResolvedAutowireMode() == AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR);
ConstructorArgumentValues resolvedValues = null;
int minNrOfArgs;
if (explicitArgs != null) {
minNrOfArgs = explicitArgs.length;
}
else {
//提取配置文件中配置的构造函数参数
ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues();
//用于承载解析后的构造函数参数的值
resolvedValues = new ConstructorArgumentValues();
//能解析到的参数个数
minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);
}
//排序给定的构造函数,public构造函数优先参数数量降序,非public构造函数参数数量降序
AutowireUtils.sortConstructors(candidates);
int minTypeDiffWeight = Integer.MAX_VALUE;
Set<Constructor<?>> ambiguousConstructors = null;
Deque<UnsatisfiedDependencyException> causes = null;
for (Constructor<?> candidate : candidates) {
int parameterCount = candidate.getParameterCount();
if (constructorToUse != null && argsToUse != null && argsToUse.length > parameterCount) {
//如果已经找到选用的构造函数或者需要的参数个数小于当前的构造函数参数个数则终止,因为已经按照参数个数降序排序
break;
}
if (parameterCount < minNrOfArgs) {
//参数个数不等
continue;
}
ArgumentsHolder argsHolder;
Class<?>[] paramTypes = candidate.getParameterTypes();
if (resolvedValues != null) {
//有参数则根据值构造对应参数类型的参数
try {
//注解上获取参数名称
String[] paramNames = ConstructorPropertiesChecker.evaluate(candidate, parameterCount);
if (paramNames == null) {
//获取参数名称探索器
ParameterNameDiscoverer pnd = this.beanFactory.getParameterNameDiscoverer();
if (pnd != null) {
//获取指定构造函数的参数名称
paramNames = pnd.getParameterNames(candidate);
}
}
//根据名称和数据类型创建参数持有者
argsHolder = createArgumentArray(beanName, mbd, resolvedValues, bw, paramTypes, paramNames,
getUserDeclaredConstructor(candidate), autowiring, candidates.length == 1);
}
catch (UnsatisfiedDependencyException ex) {
if (logger.isTraceEnabled()) {
logger.trace("Ignoring constructor [" + candidate + "] of bean '" + beanName + "': " + ex);
}
// Swallow and try next constructor.
if (causes == null) {
causes = new ArrayDeque<>(1);
}
causes.add(ex);
continue;
}
}
else {
// Explicit arguments given -> arguments length must match exactly.
if (parameterCount != explicitArgs.length) {
continue;
}
//构造函数没有参数的情况
argsHolder = new ArgumentsHolder(explicitArgs);
}
//探测是否有不确定性的构造函数存在,例如不同构造函数的参数为父子关系
int typeDiffWeight = (mbd.isLenientConstructorResolution() ?
argsHolder.getTypeDifferenceWeight(paramTypes) : argsHolder.getAssignabilityWeight(paramTypes));
//如果它代表着当前最接近的匹配则选作构造函数
if (typeDiffWeight < minTypeDiffWeight) {
constructorToUse = candidate;
argsHolderToUse = argsHolder;
argsToUse = argsHolder.arguments;
minTypeDiffWeight = typeDiffWeight;
ambiguousConstructors = null;
}
else if (constructorToUse != null && typeDiffWeight == minTypeDiffWeight) {
if (ambiguousConstructors == null) {
ambiguousConstructors = new LinkedHashSet<>();
ambiguousConstructors.add(constructorToUse);
}
ambiguousConstructors.add(candidate);
}
}
if (constructorToUse == null) {
if (causes != null) {
UnsatisfiedDependencyException ex = causes.removeLast();
for (Exception cause : causes) {
this.beanFactory.onSuppressedException(cause);
}
throw ex;
}
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Could not resolve matching constructor " +
"(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities)");
}
else if (ambiguousConstructors != null && !mbd.isLenientConstructorResolution()) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Ambiguous constructor matches found in bean '" + beanName + "' " +
"(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities): " +
ambiguousConstructors);
}
if (explicitArgs == null && argsHolderToUse != null) {
//将解析的构造函数放入缓存
argsHolderToUse.storeCache(mbd, constructorToUse);
}
}
Assert.state(argsToUse != null, "Unresolved constructor arguments");
//将构建的实例加入BeanWrapper中
bw.setBeanInstance(instantiate(beanName, mbd, constructorToUse, argsToUse));
return bw;
}
总览一下整个函数,其实现的功能考虑了以下几个方面。
(1)构造函数参数的确定
根据explicitArgs参数判断
如果传入的参数explicitArgs不为空,那边可以直接确定参数,因为explicitArgs参数是在调用bean的时候用户指定的;
缓存中获取
构造函数参数已经记录在缓存中,那么便可以直接拿来使用。而且这里要提到,缓存中缓存的可能是参数的最终类型也可能是参数的初始类型;
配置文件读取
如果不能根据传入的参数explicitArgs确定构造函数的参数也无法从缓存中得到相关信息,那么只能开始新一轮的分析。
分析从获取配置文件中配置的构造函数信息开始,经过之前的分析,我们知道,Spring中配置文件中的信息经过转化都会通过BeanDefinition实例承载,也就是参数mbd中包含,那么 可以通过调用mbd.getConstructorArgumentValues()来获取配置的构造函数的信息。有了配置中的信息便可以获取对应的参数值信息,获取参数值的信息包括直接指定值,如:直接指定值是某个值的原始类型String,或者是一个对其他bean的引用,而这一处理委托给resolveConstructorArguments方法,并返回能解析到的参数的个数;
(2)构造函数的确定
经过第一步后已经确定了构造函数的参数,接下来的任务就是根据构造函数参数确定构造函数,而匹配的方法就是根据参数个数匹配。
由于在配置文件中并不是唯一限制使用参数位置索引的方式去创建,同样还支持指定参数名称进行设定参数值,那么这种情况就需要确定构造函数中的参数名称。获取方式有两种:一种是通过注解的方式直接获取,另一种就是使用Spring中提供的工具类ParameterNameDiscoverer来获取。
(3)根据确定的构造函数转换对应的参数类型
(4)构造函数不确定性的验证
(5)根据实例化策略以及得到的构造函数及构造函数参数实例化bean
b、instantiateBean
经历了带参数的构造函数的实例构造,相信你会非常轻松愉快地理解不带参数的构造函数的实例化过程。
protected BeanWrapper instantiateBean(String beanName, RootBeanDefinition mbd) {
try {
Object beanInstance;
if (System.getSecurityManager() != null) {
beanInstance = AccessController.doPrivileged(
(PrivilegedAction<Object>) () -> getInstantiationStrategy().instantiate(mbd, beanName, this),
getAccessControlContext());
}
else {
beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, this);
}
BeanWrapper bw = new BeanWrapperImpl(beanInstance);
initBeanWrapper(bw);
return bw;
}
catch (Throwable ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
}
}
此方法没有什么实质性的逻辑,带有参数的实例构造中,Spring把精力都放在了构造函数以及参数匹配上,所以没有参数的话那将是非常简单的一件事,直接调用实例化策略进行实例化就可以了。
c、实例化策略
@Override
public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
//如果有需要覆盖或者动态替换的方法则当然需要使用cglib进行动态代理,因为可以在创建代理的同时将动态方法织入类中,
//但是如果没有需要动态改变得方法,为了方便直接反射就可以
if (!bd.hasMethodOverrides()) {
Constructor<?> constructorToUse;
synchronized (bd.constructorArgumentLock) {
constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;
if (constructorToUse == null) {
final Class<?> clazz = bd.getBeanClass();
if (clazz.isInterface()) {
throw new BeanInstantiationException(clazz, "Specified class is an interface");
}
try {
if (System.getSecurityManager() != null) {
constructorToUse = AccessController.doPrivileged(
(PrivilegedExceptionAction<Constructor<?>>) clazz::getDeclaredConstructor);
}
else {
constructorToUse = clazz.getDeclaredConstructor();
}
bd.resolvedConstructorOrFactoryMethod = constructorToUse;
}
catch (Throwable ex) {
throw new BeanInstantiationException(clazz, "No default constructor found", ex);
}
}
}
return BeanUtils.instantiateClass(constructorToUse);
}
else {
// Must generate CGLIB subclass.
return instantiateWithMethodInjection(bd, beanName, owner);
}
}
Spring没有直接使用最简单的反射方法来构造实例对象,是因为Spring在实例前先判断用户有没有使用replace和lookup的配置方法。如果没有,直接使用反射的方式,简单快捷,如果有,就必须使用动态代理的方式将两个特性所对应的拦截增强器设置进去,这样可以保证在调用方法的时候会被相应的拦截器增强,返回值为包含拦截器的代理实例。
7.2记录创建bean的ObjectFactory
在doCreate函数中有这样一段代码:
// Eagerly cache singletons to be able to resolve circular references
// even when triggered by lifecycle interfaces like BeanFactoryAware.
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isTraceEnabled()) {
logger.trace("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
//为避免后期循环依赖,可以在bean初始化完成前将创建实例的ObjectFactory加入工厂
//对bean再一次依赖引用,主要应用smartInstantiationAware BeanPostProcessor
//其中我们熟知的aop就是在这里将advice动态的织入bean中,若没有则直接返回bean,不做任何处理
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
这段代码不是很复杂,但是很多人不太理解这段代码的作用,而且,这段代码仅从此函数中去理解也很难弄懂其中的含义,我们需要从全局的角度去思考Spring的依赖解决办法。
- earlySingletonExposure:从字面意思就是提早曝光的单例,我们暂不定义它的学名叫什么,我们感兴趣的是哪些条件影响这个值;
- mbd.isSingleton():没有太多可以解释的,此RootBeanDefinition代表的是否是单例;
- this.allowCircularReferences:是否允许循环依赖;
- isSingletonCurrentlyInCreation(beanName):该bean是否在创建中。在Spring中,会有个专门的属性默认为DefaultSingletonBeanRegistry的singletonsCurrentlyInCreation来记录bean的加载状态,在bean开始创建前会将beanName记录属性,在bean创建结束后会将beanName从属性中移除;
经过以上分析,变量earlySingletonExposure是是否单例,是否允许循环依赖,是否对应bean正在创建的综合。当满足这3个条件,会执行addSingletonFactory操作。
还是以最简单的AB循环依赖为例,类A中含有属性类B,而类B中又含有属性类A,那么初始化A的过程如图所示:
整个流程中,其实最关键的就是getBean(A)这个过程,这决定了你是进去死循环还是顺利完成创建。在之前的代码中已经讲过,getBean(A)并不是直接实例化,而是先去缓存中检查是否有已经创建好的对应的bean,或者是已经创建好的ObjectFactory,而此时对于A的ObjectFactory早已创建,所以便不会再去向后执行,而是直接调用ObjectFactory去创建A,这里最关键的就是ObjectFactory的实现。
protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
Object exposedObject = bean;
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (SmartInstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().smartInstantiationAware) {
exposedObject = bp.getEarlyBeanReference(exposedObject, beanName);
}
}
return exposedObject;
}
7.3属性注入
在了解循环依赖的时候,我们曾反复提到了populateBean这个函数,知道它的主要功能是属性填充,那么是如何实现的呢?
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 {
//没有可填充的属性
return;
}
}
//给instantiationAwareBeanPostProcessors最后一次机会在属性设置前来改变bean
//如:可以用来支持属性注入的类型
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
//返回值为是否继续填充bean
if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
//如果后处理器发出停止填充命令则终止后续的执行
return;
}
}
}
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
int resolvedAutowireMode = mbd.getResolvedAutowireMode();
if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
//根据名称自动注入
if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
//根据类型自动注入
if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}
//后处理器已经初始化
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
//需要依赖检查
boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);
PropertyDescriptor[] filteredPds = null;
if (hasInstAwareBpps) {
if (pvs == null) {
pvs = mbd.getPropertyValues();
}
for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
PropertyValues pvsToUse = bp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
if (filteredPds == null) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
//对所有需要依赖检查的属性,进行后处理
pvsToUse = bp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
return;
}
}
pvs = pvsToUse;
}
}
if (needsDepCheck) {
if (filteredPds == null) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
checkDependencies(beanName, mbd, filteredPds, pvs);
}
//将属性应用到bean中
if (pvs != null) {
applyPropertyValues(beanName, mbd, bw, pvs);
}
}
在populateBean函数中提供了这样的处理流程。
- InstantiationAwareBeanPostProcessors处理器的postProcessAfterInstantiation函数的应用,此函数可以控制程序是否继续进行属性填充;
- 根据注入类型(byName/byType),提取依赖的bean,并统一存入PropertyValues中;
- 应用InstantiationAwareBeanPostProcessors处理器的postProcessPropertyValues方法,对属性获取完毕填充前对属性的再次处理,典型应用是RequiredAnnotationBeanPostProcessor类中对属性的验证;
- 将所有PropertyValues中的属性填充至BeanWrapper中;
a、autowireByName
根据注入类型(byName/byType),提取依赖的bean,并统一存入PropertyValues中,那么我们首先了解下byName功能是如何实现的。
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.isTraceEnabled()) {
logger.trace("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");
}
}
}
}
b、autowireByType
autowireByType与autowireByName对于我们理解与使用来说复杂程度都很相似,但是其实现功能的复杂度却完全不一样。
protected void autowireByType(
String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
TypeConverter converter = getCustomTypeConverter();
if (converter == null) {
converter = bw;
}
Set<String> autowiredBeanNames = new LinkedHashSet<>(4);
//寻找bw中需要依赖注入的属性
String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
for (String propertyName : propertyNames) {
try {
PropertyDescriptor pd = bw.getPropertyDescriptor(propertyName);
if (Object.class != pd.getPropertyType()) {
//探测指定属性的set方法
MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd);
// Do not allow eager init for type matching in case of a prioritized post-processor.
boolean eager = !(bw.getWrappedInstance() instanceof PriorityOrdered);
DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager);
//解析指定beanName的属性所匹配的值,并把解析到的属性名称存储在autowiredBeanNames中,当属性存在多个封装bean时,如@Autowired private List<A> aList;将所有匹配A类型的bean并将其注入
Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter);
if (autowiredArgument != null) {
pvs.add(propertyName, autowiredArgument);
}
for (String autowiredBeanName : autowiredBeanNames) {
//注册依赖
registerDependentBean(autowiredBeanName, beanName);
if (logger.isTraceEnabled()) {
logger.trace("Autowiring by type from bean name '" + beanName + "' via property '" +
propertyName + "' to bean named '" + autowiredBeanName + "'");
}
}
autowiredBeanNames.clear();
}
}
catch (BeansException ex) {
throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName, propertyName, ex);
}
}
}
public Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName,
@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {
descriptor.initParameterNameDiscovery(getParameterNameDiscoverer());
if (Optional.class == descriptor.getDependencyType()) {
return createOptionalDependency(descriptor, requestingBeanName);
}
else if (ObjectFactory.class == descriptor.getDependencyType() ||
ObjectProvider.class == descriptor.getDependencyType()) {
//ObjectFactory类注入的特殊处理
return new DependencyObjectProvider(descriptor, requestingBeanName);
}
else if (javaxInjectProviderClass == descriptor.getDependencyType()) {
//javaxInjectProviderClass类注入的特殊处理
return new Jsr330Factory().createDependencyProvider(descriptor, requestingBeanName);
}
else {
Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(
descriptor, requestingBeanName);
if (result == null) {
//通用处理逻辑
result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
}
return result;
}
}
public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName,
@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {
InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor);
try {
Object shortcut = descriptor.resolveShortcut(this);
if (shortcut != null) {
return shortcut;
}
Class<?> type = descriptor.getDependencyType();
//用于支持Spring中新增的注解@Value
Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);
if (value != null) {
if (value instanceof String) {
String strVal = resolveEmbeddedValue((String) value);
BeanDefinition bd = (beanName != null && containsBean(beanName) ?
getMergedBeanDefinition(beanName) : null);
value = evaluateBeanDefinitionString(strVal, bd);
}
TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
try {
return converter.convertIfNecessary(value, type, descriptor.getTypeDescriptor());
}
catch (UnsupportedOperationException ex) {
// A custom TypeConverter which does not support TypeDescriptor resolution...
return (descriptor.getField() != null ?
converter.convertIfNecessary(value, type, descriptor.getField()) :
converter.convertIfNecessary(value, type, descriptor.getMethodParameter()));
}
}
Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
if (multipleBeans != null) {
return multipleBeans;
}
Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
if (matchingBeans.isEmpty()) {
if (isRequired(descriptor)) {
raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
}
return null;
}
String autowiredBeanName;
Object instanceCandidate;
if (matchingBeans.size() > 1) {
autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);
if (autowiredBeanName == null) {
if (isRequired(descriptor) || !indicatesMultipleBeans(type)) {
return descriptor.resolveNotUnique(descriptor.getResolvableType(), matchingBeans);
}
else {
// In case of an optional Collection/Map, silently ignore a non-unique case:
// possibly it was meant to be an empty collection of multiple regular beans
// (before 4.3 in particular when we didn't even look for collection beans).
return null;
}
}
instanceCandidate = matchingBeans.get(autowiredBeanName);
}
else {
// We have exactly one match.
Map.Entry<String, Object> entry = matchingBeans.entrySet().iterator().next();
autowiredBeanName = entry.getKey();
instanceCandidate = entry.getValue();
}
if (autowiredBeanNames != null) {
autowiredBeanNames.add(autowiredBeanName);
}
if (instanceCandidate instanceof Class) {
instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this);
}
Object result = instanceCandidate;
if (result instanceof NullBean) {
if (isRequired(descriptor)) {
raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
}
result = null;
}
if (!ClassUtils.isAssignableValue(type, result)) {
throw new BeanNotOfRequiredTypeException(autowiredBeanName, type, instanceCandidate.getClass());
}
return result;
}
finally {
ConstructorResolver.setCurrentInjectionPoint(previousInjectionPoint);
}
}
c、applyPropertyValues
程序运行到这里,已经完成了对所有注入属性的获取,但是获取的属性是以PropertyValues形式存在,还没有应用到已经实例化的bean中,这一工作是在applyPropertyValues中。
protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
if (pvs.isEmpty()) {
return;
}
//属性注入时,会对beanWrapper类型做特殊处理
if (System.getSecurityManager() != null && bw instanceof BeanWrapperImpl) {
((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext());
}
MutablePropertyValues mpvs = null;
List<PropertyValue> original;
//如果mpvs中的值已经被转换为对应的类型那么可以直接设置到beanWrapper中
if (pvs instanceof MutablePropertyValues) {
mpvs = (MutablePropertyValues) pvs;
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();
if (originalValue == AutowiredPropertyMarker.INSTANCE) {
Method writeMethod = bw.getPropertyDescriptor(propertyName).getWriteMethod();
if (writeMethod == null) {
throw new IllegalArgumentException("Autowire marker for property without write method: " + pv);
}
originalValue = new DependencyDescriptor(new MethodParameter(writeMethod, 0), true);
}
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 {
bw.setPropertyValues(new MutablePropertyValues(deepCopy));
}
catch (BeansException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Error setting property values", ex);
}
}
7.4初始化bean
bean配置时bean中有一个init-method的属性,这个属性的作用是在bean实例化前调用init-method指定的方法来初始化。
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
//激活aware方法
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {
//对特殊的bean的处理:Aware、BeanClassLoaderAware、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;
}
虽然说此函数的主要目的是进行客户设定的初始化方法的调用,但是除此之外还有些其他必要的方法。
a、激活aware方法
在分析其原理之前,我们先了解一下Aware的使用。Spring中提供了一些Aware相关接口,比如BeanFactoryAware、ApplicationContextAware、ResourceLoaderAware、ServletContextAware等,实现这些Aware接口的bean在被初始化之后,可以取得一些相对应的资源,例如实现BeanFactoryAware的bean初始化后,Spring容器将会注入BeanFactory的实例。
当然其他aware的使用方法都大同小异,看一下Spring的实现方式,相信大家就知道了:
private void invokeAwareMethods(String beanName, 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);
}
}
}
b、处理器的应用
BeanPostProcessor相信大家都不陌生,这是Spring中开放式框架中一个必不可少的亮点,给用户充足的权限去更改或者扩展Spring。BeanPostProcessor的使用位置就是这里,在调用客户自定义初始化方法前以及调用自定义初始化方法后分别会调用BeanPostProcessor的postProcessBeforeInitialization和postProcessAfterInitialization方法,使用户可以根据自己的业务需求进行响应的处理。
@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;
}
c、激活自定义的init方法
客户定制的初始化方法除了我们熟知的使用配置init-method外,还有使用自定义的bean实现InitializingBean接口,并在afterPropertiesSet中实现自己的初始化业务逻辑。
init-method与afterPropertiesSet都是在初始化bean时执行,执行顺序是afterPropertiesSet先执行,而init-method后执行。
protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBeanDefinition mbd)
throws Throwable {
//首先会检查是否是InitializingBean,如果是的话需要调用afterPropertiesSet方法
boolean isInitializingBean = (bean instanceof InitializingBean);
if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
if (logger.isTraceEnabled()) {
logger.trace("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);
}
}
}
7.5注册DisposableBean
Spring中不但提供了对于初始化方法的扩展入口,同样也提供了销毁方法的扩展入口,对于销毁方法的扩展,除了我们熟知的配置属性destroy-method方法外,用户还可以注册后处理器DestructionAwareBeanPostProcessor来统一处理bean的销毁方法,代码如下:
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()) {
//单例模式下注册需要销毁的bean,此方法中会处理实现DisposableBean的bean,
//并对所有的bean使用DestructionAwareBeanPostProcessors处理
registerDisposableBean(beanName, new DisposableBeanAdapter(
bean, beanName, mbd, getBeanPostProcessorCache().destructionAware, acc));
}
else {
//自定义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, getBeanPostProcessorCache().destructionAware, acc));
}
}
}