上两集说了:
- DefaultListableBeanFactory这个大管家、以及XmlBeanDefinitionReader和XmlBeanFactory争风吃醋的故事
- 默认标签和自定义标签解析过程
默认标签和自定义标签的解析就是Spring将bean从配置文件到加载到内存中的全过程,那咱们把bean从配置文件中按照人家配置文件编写者的要求或者说设计想法抠出来并加载到内存中之后,该干吗了,不就是加载bean,然后把bean扔到Spring容器中,按需分配呗
,开唠。
PART1:bean的加载:
bean这天先看了上面两篇文章后,直接眼睛红了+火冒三丈,就吼起来了。
bean:哎,AiYWM编剧,叨叨叨半天,我就大概知道你前两篇就是为把bean装进容器中做准备,而这一篇是真正把bean装进容器中,是吧?,别搞半天还是再做准备工作,这谁受得了,该切入主题了。
AiYWM:差不多,我也是第一次,你见谅一下,咱们是动态进行的,这其实道理很简单,你干啥事之前也不能确保100%准备工作都做好,只能准备大概,然后做做看,缺啥补啥继续干就行,而且你想,这个bean加载出来应该放哪里,是不是放到某个地方等待被调用,而咱们一般是 用getBean方法来获取Spring容器中已初始化的bean,所以咱们看看getBean方法的return后面那一坨不就相当于找到了bean加载的源码了嘛
。不和你废话了,咱们整,上菜。
public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport implements ConfigurableBeanFactory {
@Override
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}
...
@SuppressWarnings("unchecked")
protected <T> T doGetBean(
String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
throws BeansException {
//提取对应的beanName
String beanName = transformedBeanName(name);
Object beanInstance;
// Eagerly check singleton cache for manually registered singletons.
//直接尝试从缓存获取对应bean实例或者从singletonFactories中的ObjectFactory实例工厂中获取bean实例,再获取之前肯定得先检查一下缓存中或者实例工厂中是否有对应的实例,因为创建单例bean时会进行依赖注入,而依赖注入时就会发生循环依赖,所以为了避免循环依赖,Spring创建bean时不等bean创建完成就会将创建bean的bean实例工厂提早加入缓存中,一旦下一个bean创建时需要用到实例工厂则或者说需要依赖上个bean则直接使用即可,因为咱们缓存中已经有了呀
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 + "'");
}
}
//返回对应的实例,有时候存在这样一种情况,比如BeanFactory不是直接返回实例本身而是返回指定方法返回的实例
beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
else {
// Fail if we're already creating this bean instance:
// We're assumably within a circular reference.
//因为只有在单例情况下才会尝试解决循环依赖,原型模式情况下如果存在A中有B的属性B中也有A的属性,那么当依赖注入是就会产生当A还未创建完成时由于B创建而再次返回创建A,造成循环依赖,就是这种情况
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
// Check if bean definition exists in this factory.
BeanFactory parentBeanFactory = getParentBeanFactory();
//如果beanDefinitionMap中也就是在所有已经加载的类中不包括beanName,则尝试从parentBeanFactory中检测
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// Not found -> check parent.
String nameToLookup = originalBeanName(name);
if (parentBeanFactory instanceof AbstractBeanFactory abf) {
return abf.doGetBean(nameToLookup, requiredType, args, typeCheckOnly);
}
//递归到BeanFactory中寻找
else if (args != null) {
// Delegation to parent with explicit args.
return (T) parentBeanFactory.getBean(nameToLookup, args);
}
else if (requiredType != null) {
// No args -> delegate to standard getBean method.
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配置文件的GenericBeanDefinition转换为RootBeanDefinition,如果指定BeanName是子Bean的话同时会合并父类的相关属性
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);
// Guarantee initialization of beans that the current bean depends on.
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);
}
}
}
// Create bean instance.
//实例化依赖的bean后就可以实例化mbd本身了
if (mbd.isSingleton()) {
//getSingleton方法首先尝试从singletonObjects里面获取实例,如果获取不到再从earlySingleton Objects里面获取,如果还获取不到,再尝试从singletonFactories里面获取beanName对应的ObjectFactory,然后调用这个ObjectFactory的getObject来创建bean,并放到earlySingleton Objects里面去,并且从singletonFacotories里面remove掉这个ObjectFactory,而对于后续的所有内存操作都只为了循环依赖检测时候使用,也就是在allowEarlyReference为true的情况下才会使用。
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);
}
//prototype模式的创建或者叫实例化
else if (mbd.isPrototype()) {
// It's a prototype -> create a new instance.
Object prototypeInstance = null;
try {
beforePrototypeCreation(beanName);
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
beanInstance = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
else {
//在指定的scope上实例化bean
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);
}
...
@SuppressWarnings("unchecked")
<T> T adaptBeanInstance(String name, Object bean, @Nullable Class<?> requiredType) {
// Check if required type matches the type of the actual bean instance.
//检查需要的类型是否符合bean的实际类型
if (requiredType != null && !requiredType.isInstance(bean)) {
try {
Object convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
if (convertedBean == null) {
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
return (T) convertedBean;
}
catch (TypeMismatchException ex) {
if (logger.isTraceEnabled()) {
logger.trace("Failed to convert bean '" + name + "' to required type '" +
ClassUtils.getQualifiedName(requiredType) + "'", ex);
}
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
}
return (T) bean;
}
...
}
看完就得理一理整个bean加载过程具体细节了:如下:
- 整个Spring加载bean的过程:
执行玩下面这几步bean的加载就结束了,这个时候就可以返回我们所需要的bean了
- 将形参中传进来的name转换对应的beanName:String beanName = transformedBeanName(name);这个name有可能是FactoryBean对应的名字也有可能是别名(比如别名A指向名称为B的bean则返回B,别名A指向别名B,别名B又指向名称为C的bean则返回C)
- FactoryBean:一个东西一般不可能平白无故产生,肯定有他存在的理由。Spring提供了一个org.Springframework.bean.factory.FactoryBean的工厂类接口,是因为有时在某些情况下,实例化bean过程比较复杂,如果按照传统的方式,则需要在中提供大量的配置信息,配置方式的灵活性是受限的,这时采用编码的方式可能会得到一个简单的方案,所以Spring提供这个工厂类接口使得
用户可以通过实现这个工厂类接口从而定制实例化bean【隐藏了实例化一些复杂bean的细节,给上层应用带来了便利。】
,Spring框架自身提供了70多个FactoryBean的实现
public interface FactoryBean<T> { String OBJECT_TYPE_ATTRIBUTE = "factoryBeanObjectType"; @Nullable //返回由FactoryBean创建的bean实例,如果isSingleton()返回true,则该实例会放到Spring容器中单实例缓存池中。 T getObject() throws Exception; @Nullable Class<?> getObjectType();//返回FactoryBean创建的bean类型 //返回由FactoryBean创建的bean实例的作用域是singleton还是prototype。 default boolean isSingleton() { return true; } }
- 当配置文件中的class属性配置的实现类是FactoryBean时【public class XxxFactoryBean implements FactoryBean】,通过getBean()方法返回的不是FactoryBean本身,而是FactoryBean#getObject()方法所返回的对象,
相当于FactoryBean#getObject()代理了getBean()方法
。或者说FactoryBean的调用方法是,如果bean声明为FactoryBean类型,则当提取bean时提取的并不是FactoryBean,而是FactoryBean中对应的getObject方法返回的bean,而doGetObjectFromFactoryBean正是实现这个功能的。哪个doGetObjectFromFactoryBean方法呀,你往下翻,最终在缓存中找不到bean时就会调用FactoryBean的getObject方法得到bean,而这个逻辑或者说这几句代码就是在人家doGetObjectFromFactoryBean肚子里面写着呢
- 这个的话
Spring源码深度解析中有个例子
很好,贴到这以供日后查询:
- 当配置文件中的class属性配置的实现类是FactoryBean时【public class XxxFactoryBean implements FactoryBean】,通过getBean()方法返回的不是FactoryBean本身,而是FactoryBean#getObject()方法所返回的对象,
- FactoryBean:一个东西一般不可能平白无故产生,肯定有他存在的理由。Spring提供了一个org.Springframework.bean.factory.FactoryBean的工厂类接口,是因为有时在某些情况下,实例化bean过程比较复杂,如果按照传统的方式,则需要在中提供大量的配置信息,配置方式的灵活性是受限的,这时采用编码的方式可能会得到一个简单的方案,所以Spring提供这个工厂类接口使得
- 从缓存中加载单例
单例意思就是在Spring的同一个容器中只会被创建一次
,后期再获取bean直接从单例缓存中获取就行- 这里也只是
首先尝试从缓存中加载
【在创建单例bean的时候会存在依赖注入的情况,而在创建依赖的时候为了避免循环依赖, Spring创建bean的原则是不等bean创建完成就会将创建bean的ObjectFactory提早曝光加入到缓存中,一旦下一个bean创建时需要依赖上个bean,则直接使用ObjectFactory】,如果从缓存中加载不成功则从singletonFactories中加载。getSingleton方法首先检查之后再尝试从singletonObjects里面获取实例,如果获取不到再从earlySingletonObjects里面获取实例,如果earlySingletonObjects中还获取不到bean实例,再尝试从singletonFactories里面获取beanName对应的ObjectFactory,然后调用这个ObjectFactory的getObject来创建bean,并放到earlySingleton Objects里面去,并且从singletonFacotories里面remove掉这个ObjectFactory,而对于后续的所有内存操作都只为了循环依赖检测时候使用,也就是在allowEarlyReference为true的情况下才会使用
。public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry { ... @Override @Nullable public Object getSingleton(String beanName) { return getSingleton(beanName, true); } ... public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) { Assert.notNull(beanName, "Bean name must not be null"); //首先通过锁进行这个全局变量的同步 synchronized (this.singletonObjects) { Object singletonObject = this.singletonObjects.get(beanName); //然后检查对应的bean是否已经加载过,如果加载过就可以直接复用已经创建好的bean实例,因为singleton模式其实就是复用创建的bean,所以这一步检查是必须的。如果为空就可以进行singleton的bean的初始化 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方法里面就一个if判断【if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName))】,判断完之后抛出了一个异常【throw new BeanCurrentlyInCreationException(beanName);】,其他啥也没干,除此之外里面没有任何逻辑,但是不代表这个方法是个废物,这个方法里面记录了加载状态,也就是通过this.singletonsCurrentlyIn Creation.add(beanName)将当前正要创建的bean记录在缓存中,这样便可以对循环依赖进行检测。 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; } //上面beforeSingletonCreation通过this.singletonsCurrentlyIn Creation.add(beanName)将当前正要创建的bean记录在缓存中,这里有始有终嘛,当bean加载结束后通过afterSingletonCreation方法移除缓存中对该bean的正在加载状态的记录。 afterSingletonCreation(beanName); } if (newSingleton) { //加入缓存。addSingleton方法是将结果记录至缓存并删除加载bean过程中所记录的各种辅助状态。 addSingleton(beanName, singletonObject); } } //返回处理结果 return singletonObject; } } ... @Nullable protected Object getSingleton(String beanName, boolean allowEarlyReference) { // Quick check for existing instance without full singleton lock Object singletonObject = this.singletonObjects.get(beanName); if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) { //如果singletonObject中为空也就是没有实例,再从earlySingletonObjects里面获取实例 singletonObject = this.earlySingletonObjects.get(beanName); //后续的所有内存操作都只为了循环依赖检测时候使用,也就是在allowEarlyReference为true的情况下才会使用 if (singletonObject == null && allowEarlyReference) { //因为singletonObject这货是个全局变量,咱们要考虑多线程方面的安全性,所以得加锁保持同步 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) { //如果earlySingletonObjects中为空也就是没有实例,再从singletonFactories里面获取beanName对应的ObjectFactory ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName); if (singletonFactory != null) { //然后调用singletonFactor 这个ObjectFactory的getObject来创建bean,或者叫初始化bean singletonObject = singletonFactory.getObject(); //并放到earlySingleton Objects里面去,跟咱们数据库那里一样呀,你缓存中没有,所以我得到数据库中查,从数据库中查找之后我再给你缓存中放一份副本,下次拿不就方便了嘛 this.earlySingletonObjects.put(beanName, singletonObject); //并且从singletonFacotories里面remove掉这个ObjectFactory this.singletonFactories.remove(beanName); } } } } } } return singletonObject; } ... }
- 上面的
singletonObjects、earlySingleton Objects以及singletonFactories
都是用于存储bean的不同的map
:- singletonObjects:用于保存BeanName和创建bean实例之间的关系,bean name --> bean instance。
- singletonFactories:用于保存BeanName和创建bean的工厂之间的关系,bean name -->ObjectFactory
- earlySingletonObjects:也是保存BeanName和创建bean实例之间的关系,与singletonObjects的不同之处在于,当一个单例bean被放到这里面后,那么当bean还在创建过程中,就可以通过getBean方法获取到了,其目的是用来检测循环引用。
- 通过代码咱们可以知道咱们首先是在getSingleton方法中首先检查之后再尝试从singletonObjects里面获取实例,如果获取不到再从earlySingletonObjects里面获取实例,如果earlySingletonObjects中还获取不到bean实例,
再尝试从singletonFactories里面获取beanName对应的ObjectFactory,然后调用这个ObjectFactory【ObjectFactory<?> singletonFactory,相当于singletonFactory是ObjectFactory类型的】的getObject来创建bean
,并放到earlySingleton Objects里面去,那说明bean的加载逻辑其实是在传入的ObjectFactory类型的参数singletonFactory中定义的,其实getObject方法中的主要逻辑就是这个Lamdba表达式中写的那句:调用createBean方法产生bean实例
... 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; } }); ... public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory implements AutowireCapableBeanFactory { ... @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; // Make sure bean class is actually resolved at this point, and // clone the bean definition in case of a dynamically resolved Class // which cannot be stored in the shared merged bean definition. //锁定class,根据设置的class属性或者根据className来解析Class 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(); } catch (BeanDefinitionValidationException ex) { throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(), beanName, "Validation of method overrides failed", ex); } try { // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance. //给BeanPostProcessors 一个机会来返回代理,从而让代理来替代真正的实例,其实也就是在真正调用doCreate方法创建bean的实例前使用了这样一个方法resolveBeforeInstantiation (beanName, mbd)对BeanDefinigiton中的属性做些前置处理 Object bean = resolveBeforeInstantiation(beanName, mbdToUse); //提供一个短路判断。当经过前置处理后返回的结果如果不为空,那么会直接略过后续的Bean的创建而直接返回结果,这一步其实很关键,我们熟知的AOP功能就是基于这里的判断的。也就是说,当经历过resolveBeforeInstantiation方法后,程序有两个选择,如果创建了代理或者说重写了InstantiationAwareBeanPostProcessor的postProcessBeforeInstantiation方法并在方法postProcessBeforeInstantiation中改变了bean,则直接返回就可以了,否则需要进行常规bean的创建 if (bean != null) { return bean; } } catch (Throwable ex) { throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "BeanPostProcessor before instantiation of bean failed", ex); } try { //这一个就是没有在InstantiationAwareBeanPostProcessor的postProcessBeforeInstantiation方法改变bean,则没办法直接返回bean,就需要通过doCreateBean进行常规bean的创建 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); } } ... }
- Spring配置中存在lookup-method和replace-method两个配置功能,而这两个配置的加载其实就是将配置统一存放在BeanDefinition中的methodOverrides属性里,这两个功能实现原理其实是在bean实例化的时候如果检测到存在methodOverrides属性,会动态地为当前bean生成代理并使用对应的拦截器为bean做增强处理
- Object bean = resolveBeforeInstantiation(beanName, mbdToUse);中的resolveBeforeInstantiation这个方法的源码中,最主要的就是applyBeanPostProcessorsBeforeInstantiation以及applyBeanPostProcessorsAfterInitialization这两个方法,这两个方法无非是
对后处理器中的所有InstantiationAwareBeanPostProcessor类型的后处理器进行postProcessBeforeInstantiation方法和BeanPostProcessor的postProcessAfterInitialization方法的调用
。- applyBeanPostProcessorsBeforeInstantiation方法中主要是实现实例化前的后处理器应用:bean的实例化前调用,也就是将AbsractBeanDefinition转换为BeanWrapper前的处理。
给子类一个修改BeanDefinition的机会,也就是说当程序经过这个方法后,bean可能已经不是我们认为的bean了,而是或许成为了一个经过处理的代理bean,可能是通过cglib生成的,也可能是通过其它技术生成的【当经历过resolveBeforeInstantiation方法后,程序有两个选择,如果创建了代理或者说重写了InstantiationAwareBeanPostProcessor的postProcessBeforeInstantiation方法并在方法postProcess BeforeInstantiation中改变了bean,则直接返回就可以了,否则需要进行常规bean的创建】
。public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory implements AutowireCapableBeanFactory { ... @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; } ... }
- applyBeanPostProcessorsAfterInitialization方法中主要实现实例化后的后处理器应用:Spring中的规则是在bean的初始化后尽可能保证将注册的后处理器的postProcessAfterInitialization方法应用到该bean中,因为如果返回的bean不为空,那么便不会再次经历普通bean的创建过程,所以只能在这里应用后处理器的postProcessAfterInitialization方法。
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory implements AutowireCapableBeanFactory { ... @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; } ... }
- applyBeanPostProcessorsBeforeInstantiation方法中主要是实现实例化前的后处理器应用:bean的实例化前调用,也就是将AbsractBeanDefinition转换为BeanWrapper前的处理。
- 当没有通过InstantiationAwareBeanPostProcessor的postProcessBeforeInstantiation方法改变bean,则没办法直接返回bean,
就需要通过doCreateBean进行常规bean的创建:【doCreateBean方法中创建bean的逻辑主要是如果是单例则需要首先清除缓存--->实例化bean,将BeanDefinition转换( 如果存在工厂方法则使用工厂方法进行初始化; 一个类有多个构造函数,每个构造函数都有不同的参数,所以需要根据参数锁定构造函数并进行初始化;如果既不存在工厂方法也不存在带有参数的构造函数,则使用默认的构造函数进行bean的实例化。)为BeanWrapper【Spring中用于封装bean的是BeanWrapper类型,而它又间接继承了PropertyEditorRegistry类型】--->bean合并后的处理,Autowired注解通过MergedBeanDefinitionPostProcessor方法实现诸如类型的预解析。--->依赖处理(在Spring中会有循环依赖的情况,例如,当A中含有B的属性,而B中又含有A的属性时就会构成一个循环依赖,此时如果A和B都是单例,那么在Spring中的处理方式就是当创建B的时候,涉及自动注入A的步骤时,并不是直接去再次创建A,而是通过放入缓存中的ObjectFactory来创建实例,这样就解决了循环依赖的问题。)--->属性填充过程中也就是将所有属性填充至bean的实例中--->循环依赖检查(在Sping中解决循环依赖只对单例有效,而对于prototype的bean,Spring没有好的解决办法,唯一要做的就是抛出异常。在这个步骤里面会检测已经加载的bean是否已经出现了依赖循环,并判断是否需要抛出异常。)--->注册DisposableBean:如果配置了destroy-method,这里需要注册以便于在销毁时候调用。--->完成bean的创建并返回bean】
,下面结合这个整个思路以及思路下面的代码在细细掰扯一下这个bean创建的过程:public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory implements AutowireCapableBeanFactory { ... 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 { 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正在创建中,检测循环依赖。mbd.isSingleton()表示判断此RootBeanDefinition代表的是否是单例。this.allowCircularReferences表示是否允许循环依赖。isSingletonCurrentlyInCreation(beanName)表示该bean是否在创建中。在Spring中,会有个专门的属性默认为DefaultSingletonBeanRegistry的singletonsCurrentlyInCreation来记录bean的加载状态,在bean开始创建前会将beanName记录在属性中,在bean创建结束后会将beanName从属性中移除。其实不就是哪里有个add和remove嘛 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初始化完成前将创建实例的0bjectFactory加入工厂 //这里其实相当于return getEarlyBeanReference,而这个SmartInstantiationAwareBeanPostProcessor接口中的getEarlyBeanReference方法中最后也是return bean addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean)); } // Initialize the bean instance. Object exposedObject = bean; try { //对bean进行填充,将各个属性值注入,如果存在依赖与其他bean的属性,则会递归初始依赖bean populateBean(beanName, mbd, instanceWrapper); //调用初始化方法,比如init-method。咱们平时在配置文件中进行bean配置时bean中有一个init-method的属性,这个属性的作用是在bean实例化前调用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, ex.getMessage(), 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所依赖的bean一定是已经创建的,actualDependentBeans不为空则表示当前bean创建后这个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 " + "'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example."); } } } } // Register bean as disposable. try { //根据scopse注册bean registerDisposableBeanIfNecessary(beanName, bean, mbd); } catch (BeanDefinitionValidationException ex) { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex); } return exposedObject; } } ... }
- 实例化bean,将BeanDefinition转换( 如果存在工厂方法则使用工厂方法进行初始化; 一个类有多个构造函数,每个构造函数都有不同的参数,所以需要根据参数锁定构造函数并进行初始化;如果既不存在工厂方法也不存在带有参数的构造函数,则使用默认的构造函数进行bean的实例化。)为BeanWrapper【
Spring中用于封装bean的是BeanWrapper类型
,而它又间接继承了PropertyEditorRegistry类型】- 如果在RootBeanDefinition中存在factoryMethodName属性,或者说在配置文件中配置了factory-method,那么Spring会尝试使用instantiateUsingFactoryMethod(beanName, mbd, args)方法根据RootBeanDefinition中的配置生成bean的实例。
- 解析构造函数并进行构造函数的实例化。因为一个bean对应的类中可能会有多个构造函数,而每个构造函数的参数不同,Spring在根据参数及类型去判断最终会使用哪个构造函数进行实例化。但是,判断的过程是个比较消耗性能的步骤,所以采用缓存机制,如果已经解析过则不需要重复解析而是直接从RootBeanDefinition中的属性resolvedConstructorOrFactoryMethod缓存的值去取,否则需要再次解析,并将解析的结果添加至RootBeanDefinition中的属性resolvedConstructorOrFactoryMethod中。源码中对于实例的创建Spring中分成了两种情况,一种是通用的实例化,另一种是带有参数的实例化:【
带有参数的实例构造中,Spring把精力都放在了构造函数以及参数的匹配上,所以如果没有参数的话那将直接调用实例化策略进行实例化就可以了
。】- 带有的这个参数Spring是咋确定的呢?
- 如果传入的参数explicitArgs不为空,那边可以直接确定参数,因为explicitArgs参数是在调用Bean的时候用户指定的,在BeanFactory类中存在这样的方法:Object getBean(String name, Object… args) throws BeansException;在获取bean的时候,用户不但可以指定bean的名称还可以指定bean所对应类的构造函数或者工厂方法的方法参数,主要用于静态工厂方法的调用,而这里是需要给定完全匹配的参数的,所以,便可以判断,如果传入参数explicitArgs不为空,则可以确定构造函数参数就是它。
- 除此之外也有可能构造函数参数已经记录在缓存中,那么便可以直接拿来使用。而且,在缓存中缓存的可能是参数的最终类型也可能是参数的初始类型,比如构造函数参数要求的是int类型,但是原始的参数值可能是String类型的“1”,那么即使在缓存中得到了参数,也需要经过类型转换器的过滤以确保参数类型与对应的构造函数参数类型完全对应。
- 如果不能根据传入的参数explicitArgs确定构造函数的参数也无法在缓存中得到相关信息,那么只能开始新一轮的分析了。
分析从获取配置文件中配置的构造函数信息开始,Spring中配置文件中的信息经过转换都会通过BeanDefinition实例承载,也就是参数mbd中包含,那么可以通过调用mbd.getConstructorArgumentValues()来获取配置的构造函数信息
。有了配置中的信息便可以获取对应的参数值信息了,获取参数值的信息包括直接指定值,如:直接指定构造函数中某个值为原始类型String类型,或者是一个对其他bean的引用,而这一处理委托给resolveConstructorArguments方法,并返回能解析到的参数的个数。
- 带有的这个参数Spring是咋确定的呢?
- 参数确定了那么构造函数咋确定的呢:
- 经过了第一步后已经确定了构造函数的参数,接下来的任务就是根据构造函数参数在所有构造函数中锁定对应的构造函数,
而匹配的方法就是根据参数个数匹配,所以在匹配之前需要先对构造函数按照public构造函数优先参数数量降序、非public构造函数参数数量降序
。这样可以在遍历的情况下迅速判断排在后面的构造函数参数个数是否符合条件。由于在配置文件中并不是唯一限制使用参数位置索引的方式去创建,同样还支持指定参数名称进行设定参数值的情况。获取参数名称可以有两种方式,一种是通过注解的方式直接获取,另一种就是使用Spring中提供的工具类ParameterNameDiscoverer来获取。构造函数、参数名称、参数类型、参数值都确定后就可以锁定构造函数以及转换对应的参数类型了
- 经过了第一步后已经确定了构造函数的参数,接下来的任务就是根据构造函数参数在所有构造函数中锁定对应的构造函数,
- 实例化策略是咋确定的呢?
- 得到参数以及构造函数之后,我们已经得到了足以实例化的所有相关信息,完全可以
使用最简单的反射方法直接反射来构造实例对象,但是人家Spring没用反射来干,人家Spring首先判断如果beanDefinition.getMethodOverrides()为空也就是用户没有使用replace或者lookup的配置方法,那么直接使用反射的方式,简单快捷,但是如果使用了这两个特性,在直接使用反射的方式创建实例就不妥了,因为需要将这两个配置提供的功能切入进去,所以就必须要使用动态代理的方式将包含两个特性所对应的逻辑的拦截增强器设置进去,这样才可以保证在调用方法的时候会被相应的拦截器增强,返回值为包含拦截器的代理实例。
- 得到参数以及构造函数之后,我们已经得到了足以实例化的所有相关信息,完全可以
- 然后就可以根据实例化策略以及得到的构造函数及构造函数参数实例化Bean
- 实例化bean,将BeanDefinition转换Wrapper之后,也就是到了bean合并后的处理,Autowired注解通过MergedBeanDefinitionPostProcessor方法实现诸如类型的预解析。
- 预解析之后就到了依赖处理:
boolean earlySingletonExposure = ...addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));}
(在Spring中会有循环依赖的情况,例如,当A中含有B的属性,而B中又含有A的属性时就会构成一个循环依赖,此时如果A和B都是单例,那么在Spring中的处理方式就是当创建B的时候,涉及自动注入A的步骤时,并不是直接去再次创建A,而是通过放入缓存中的ObjectFactory来创建实例A
,这样就解决了循环依赖的问题。换句话说Spring处理循环依赖的解决办法,是在B中创建依赖A时通过ObjectFactory提供的实例化方法来中断A中的属性填充,使B中持有的A仅仅是刚刚初始化并没有填充任何属性的A
,而这正初始化A的步骤还是在最开始创建A的时候进行的,但是因为A与B中的A所表示的属性地址是一样的,所以在A中创建好的属性填充自然可以通过B中的A获取,这样就解决了循环依赖的问题。),这个放入缓存中的ObjectFactory到底是个啥玩意呢,咋能发挥这么大的作用:- 放入缓存中的ObjectFactory中最重要的就是getEarlyBeanReference,在getEarlyBeanReference方法中除了后处理器的调用外没有别的处理工作
- 解决循环依赖之后,就可以安心进行属性填充了【
populateBean(beanName, mbd, instanceWrapper);
】,在属性填充过程中也就是将所有属性填充至bean的实例中。在populateBean函数中提供了这样的处理流程。public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory implements AutowireCapableBeanFactory { ... @SuppressWarnings("deprecation") // for postProcessPropertyValues 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. if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) { 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); // Add property values based on autowire by name if applicable. //根据名称自动注入 if (resolvedAutowireMode == AUTOWIRE_BY_NAME) { autowireByName(beanName, mbd, bw, newPvs); } // Add property values based on autowire by type if applicable. //根据类型自动注入 if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) { autowireByType(beanName, mbd, bw, newPvs); } pvs = newPvs; } //后处理器已经初始化 boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors(); //需要依赖检查 boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE); if (hasInstAwareBpps) { if (pvs == null) { pvs = mbd.getPropertyValues(); } for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) { //对所有需要依赖检查的属性进行后处理 PropertyValues pvsToUse = bp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName); if (pvsToUse == null) { return; } pvs = pvsToUse; } } if (needsDepCheck) { PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching); checkDependencies(beanName, mbd, filteredPds, pvs); } if (pvs != null) { //将属性应用到bean中 applyPropertyValues(beanName, mbd, bw, pvs); } } ... }
- InstantiationAwareBeanPostProcessor处理器的postProcessAfterInstantiation方法可以
控制程序是否继续进行属性填充
。 根据注入类型(byName/byType),提取依赖的bean,并统一存入PropertyValues中
。这不就和咱们学的联系上了嘛。- byName是通过autowireByName方法实现的,
这个autowireByName方法中无非是在传入的参数pvs【PropertyValues pvsToUse】中找出已经加载的bean【实现根据名称自动匹配的第一步就是寻找bw中需要依赖注入的属性】,并递归实例化,进而加入到pvs【PropertyValues pvsToUse】中
。 - byType是通过autowireByType方法实现的,这个autowireByType方法中,
对于根据类型自动匹配的实现来讲第一步也是寻找bw【@Nullable BeanWrapper bw】中需要依赖注入的属性,然后遍历这些属性并寻找类型匹配的bean,而对于寻找类型匹配的逻辑实现封装在了DefaultListableBeanFactory这个大管家中的resolveDependency函数中。【寻找类型的匹配执行顺序时,首先尝试使用解析器进行解析,如果解析器没有成功解析,那么可能是使用默认的解析器没有做任何处理,或者是使用了自定义的解析器,但是对于集合等类型来说并不在解析范围之内,所以再次对不同类型进行不同情况的处理】。
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory implements AutowireCapableBeanFactory { ... 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); String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw); for (String propertyName : propertyNames) { try { PropertyDescriptor pd = bw.getPropertyDescriptor(propertyName); // Don't try autowiring by type for type Object: never makes sense, // even if it technically is an unsatisfied, non-simple property. if (Object.class != pd.getPropertyType()) { 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); 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); } } } ... }
- byName是通过autowireByName方法实现的,
- 应用InstantiationAwareBeanPostProcessor处理器的postProcessPropertyValues方法,对属性获取完毕填充前对属性的再次处理,典型应用是RequiredAnnotationBeanPostProcessor类中对属性的验证。
将所有PropertyValues中的属性填充至BeanWrapper中【Spring中用于封装bean的是BeanWrapper类型,而它又间接继承了PropertyEditorRegistry类型】
- 完成了对所有注入属性的获取之后,但是此时获取的属性是以PropertyValues形式存在的,还并没有应用到已经实例化的bean中,所以源码最后一步就是
通过applyPropertyValues将属性应用到bean中
,因为获取的属性是以PropertyValues形式存在的,还并没有应用到已经实例化的bean中
- InstantiationAwareBeanPostProcessor处理器的postProcessAfterInstantiation方法可以
- 属性填充之后,Spring心里还是没底,得再去看看你刚填充属性时有没有给我造成啥循环依赖这种趁我转过头就发生的错误,所以Spring再进行循环依赖检查(在Sping中解决循环依赖只对单例有效,而对于prototype的bean,Spring没有好的解决办法,唯一要做的就是抛出异常。
在这个步骤里面会检测已经加载的bean是否已经出现了依赖循环,并判断是否需要抛出异常
。) - Spring中提供了对于初始化方法的扩展入口:除此之外,
Spring中程序执行bean的实例化后,然后再进行了属性的填充,就会在这两步之后调用用户设定的初始化方法initializeBean
【这个initializeBean方法的主要目的是进行客户设定的初始化方法的调用,但是人家除了这一个还有几个作用】:- 1.
激活Aware
(Spring中提供一些Aware相关接口,比如BeanFactoryAware、ApplicationContextAware、ResourceLoaderAware、ServletContextAware等,实现这些Aware接口的bean在被初始之后,可以取得一些相对应的资源,然后也可以实现一些搔操作:
- 这里贴上郝老师团队的Spring源码深度解析这本书上的一个很好的例子,以备日后查阅学习:
- 这里贴上郝老师团队的Spring源码深度解析这本书上的一个很好的例子,以备日后查阅学习:
- 2.
处理器的应用
:Spring中开放式架构中有一个必不可少的亮点,就是给用户充足的权限去更改或者扩展Spring【在调用客户自定义初始化方法前以及调用自定义初始化方法后分别会调用BeanPostProcessor的postProcessBeforeInitialization和postProcessAfterInitialization方法,使用户可以根据自己的业务需求进行响应的处理。】
,除了BeanPostProcessor外还有很多其他的PostProcessor,当然大部分都是以此BeanPostProcessor为基础,继承自BeanPostProcessor - 3.
激活自定义的init方法
:客户定制的初始化方法除了我们熟知的使用配置init-method外,还有使自定义的bean实现InitializingBean接口,并在afterPropertiesSet中实现自己的初始化业务逻辑【init-method与afterPropertiesSet都是在初始化bean时执行,执行顺序是afterPropertiesSet先执行,而init-method后执行。】。
- 1.
- Spring中不但提供了对于初始化方法的扩展入口,同样也提供了销毁方法的扩展入口:单例和非单例的循环依赖都搞完之后,就该注册DisposableBean:如果配置了destroy-method,这里需要注册以便于在销毁时候调用。对于销毁方法的扩展,除了我们熟知的配置属性destroy-method方法外,用户还可以注册后处理器DestructionAwareBeanPostProcessor来统一处理bean的销毁方法
- 注册完了之后,就相当于完成bean的创建了,然后返回bean就行了
- 实例化bean,将BeanDefinition转换( 如果存在工厂方法则使用工厂方法进行初始化; 一个类有多个构造函数,每个构造函数都有不同的参数,所以需要根据参数锁定构造函数并进行初始化;如果既不存在工厂方法也不存在带有参数的构造函数,则使用默认的构造函数进行bean的实例化。)为BeanWrapper【
如果缓存没有数据的话直接转到父类工厂上去加载了
无论是从缓存中获取到的bean还是通过不同的scope策略加载的bean都只是最原始的bean状态,就是没穿衣服裸奔的bean,并不一定是我们最终想要的bean或者说想用的bean,咱们最终想要的bean或者最后能用的bean可能还需要把这个bean再传入某个方法中处理一下再给咱们返回一个最终版bean
- bean的实例化:如果从缓存中得到了bean的原始状态则需要对bean进行实例化,咱们上面费尽力气的得到Object,可不就是个Object,咱们都想看到这个:return bean,对吧,其实加载完之后,到这一步就是
通过调用参数传入的ObjectFactory的个体Object方法实例化bean
。- 无论是
从缓存中获得bean还是根据不同的scope策略加载获得的bean【无论是从缓存中获取到的bean还是通过不同的scope策略加载的bean都只是最原始的bean状态,就是没穿衣服裸奔的bean,并不一定是我们最终想要的bean或者说想用的bean,咱们最终想要的bean或者最后能用的bean可能还需要把这个bean再传入某个方法中处理一下再给咱们返回一个最终版bean】
,实例后要做的第一步就是调用这个方法来检测一下正确性,其实就是用于检测当前bean是否是FactoryBean类型的bean
,如果是,那么需要调用该bean对应的FactoryBean实例中的getObject()作为返回值。而看咱们doGetBean方法中有这么四句代码值得深思:- beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, null);
- beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
- beanInstance = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
- beanInstance = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
protected Object getObjectForBeanInstance( Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) { // Don't let calling code try to dereference the factory if the bean isn't a factory. //如果指定的name是工厂相关(以&为前缀) if (BeanFactoryUtils.isFactoryDereference(name)) { if (beanInstance instanceof NullBean) { return beanInstance; } //而且beanInstance又不是FactoryBean类型则验证不通过 if (!(beanInstance instanceof FactoryBean)) { throw new BeanIsNotAFactoryException(beanName, beanInstance.getClass()); } if (mbd != null) { mbd.isFactoryBean = true; } return beanInstance; } // Now we have the bean instance, which may be a normal bean or a FactoryBean. // If it's a FactoryBean, we use it to create a bean instance, unless the // caller actually wants a reference to the factory. if (!(beanInstance instanceof FactoryBean<?> factoryBean)) { return beanInstance; } Object object = null; if (mbd != null) { mbd.isFactoryBean = true; } else { //尝试从缓存中获取bean object = getCachedObjectForFactoryBean(beanName); } //到这一步已经可以明确beanInstance一定是FactoryBean类型 if (object == null) { // Return bean instance from factory. // Caches object obtained from FactoryBean if it is a singleton. //containsBeanDefinition检测beanDefinitionMap中(也就i是在所有已经加载的类中)检测是否定义beanName if (mbd == null && containsBeanDefinition(beanName)) { mbd = getMergedLocalBeanDefinition(beanName); } //是否是用户定义的而不是应用程序本身定义的 boolean synthetic = (mbd != null && mbd.isSynthetic()); //将存储XML配置文件的GernericBeanDefinition转换为RootBeanDefinition,如果指定BeanName是子Bean的话同时会合并父类的相关属性 object = getObjectFromFactoryBean(factoryBean, beanName, !synthetic); } return object; }
- 而从上面的代码中可以看出,返回的object还是经过getObjectFromFactoryBean方法处理的【
getObjectForBeanInstance将从Factory中解析bean的工作委托给getObjectFromFactoryBean
】,public abstract class FactoryBeanRegistrySupport extends DefaultSingletonBeanRegistry { ... protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) { //如果是单例模式 if (factory.isSingleton() && containsSingleton(beanName)) { synchronized (getSingletonMutex()) { //因为是单例的,所以不必重复创建,可以使用缓存来提高性能,也就是说已经加载过就要记录下来以便于下次复用,否则的话就直接获取了。 Object object = this.factoryBeanObjectCache.get(beanName); //缓存中没有,则需要创建才能获取 if (object == null) { 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) { if (isSingletonCurrentlyInCreation(beanName)) { // Temporarily return non-post-processed object, not storing it yet.. return object; } beforeSingletonCreation(beanName); try { 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 { //如果需要则调用ObjectFactory的后处理器 object = postProcessObjectFromFactoryBean(object, beanName); } catch (Throwable ex) { throw new BeanCreationException(beanName, "Post-processing of FactoryBean's object failed", ex); } } return object; } } ... }
- 刚说了没几句,当缓存中没有时又是经过doGetObjectFromFactoryBean方法处理后才返回object。你调用的这个getObject方法不就是人家FactoryBean接口的嘛
public abstract class FactoryBeanRegistrySupport extends DefaultSingletonBeanRegistry { ... private Object doGetObjectFromFactoryBean(FactoryBean<?> factory, String beanName) throws BeanCreationException { Object object; try { //直接调用getObject方法 object = factory.getObject(); } ... return object; } }
- 但是呀,你看上面的getObjectFromFactoryBean这个大方法中的逻辑,人家调用object = factory.getObject()得到我们想要的结果后并没有直接返回,而是接下来又做了些后处理的操作,哪些操作呢?看下面:
调用AbstractAutowireCapableBeanFactory类的postProcessObjectFromFactoryBean方法,尽可能保证所有bean初始化后都会调用注册的BeanPostProcessor的postProcessAfterInitialization方法进行处理,在实际开发过程中可以针对此特性设计自己的业务逻辑
。public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory implements AutowireCapableBeanFactory { ... @Override protected Object postProcessObjectFromFactoryBean(Object object, String beanName) { return applyBeanPostProcessorsAfterInitialization(object, beanName); } ... @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; } ... }
- 无论是
- 原型模式的依赖检查:if (isPrototypeCurrentlyInCreation(beanName)) {…}
如果存在A中有B的属性,B中有A的属性,那么当依赖注入的时候,就会产生当A还未创建完的时候因为对于B的创建再次返回创建A
,循环依赖只有在单例情况下才会产生- 循环依赖:具体的循环依赖相关知识可以点点看,这一篇。
- 检测parentBeanFactory:if (parentBeanFactory != null && !containsBeanDefinition(beanName)){…}
- 如果当前加载的XML配置文件中不包含beanName所对应的配置,就只能到parentBeanFactory去尝试下了,然后再去递归的调用getBean方法。
- 将存储XML配置文件的GernericBeanDefinition转换为RootBeanDefinition
从XML配置文件中读取到的Bean信息是存储在GernericBeanDefinition中的,但是所有的Bean后续处理都是针对于RootBeanDefinition的,所以这里需要进行一个转换
,转换的同时如果父类bean不为空的话,则会一并合并父类的属性。
- 寻找依赖
- 因为bean的初始化过程中很可能会用到某些属性,而某些属性很可能是动态配置的,并且配置成依赖于其他的bean,那么这个时候就有必要先加载依赖的bean,所以,
在Spring的加载顺寻中,在初始化某一个bean的时候首先会初始化这个bean所对应的依赖
。
- 因为bean的初始化过程中很可能会用到某些属性,而某些属性很可能是动态配置的,并且配置成依赖于其他的bean,那么这个时候就有必要先加载依赖的bean,所以,
针对不同的scope进行bean的创建
:- 在Spring中存在着不同的scope,其中默认的是singleton,但是还有些其他的配置诸如prototype、request之类的。在这个步骤中,Spring会根据不同的配置进行不同的初始化策略。
无论是从缓存中获取到的bean还是通过不同的scope策略加载的bean都只是最原始的bean状态,就是没穿衣服裸奔的bean,并不一定是我们最终想要的bean或者说想用的bean,咱们最终想要的bean或者最后能用的bean可能还需要把这个bean再传入某个方法中处理一下再给咱们返回一个最终版bean
- 类型转换:
- 到这一步返回bean已经基本结束了。通常对该方法的调用参数requiredType是为空的,但是可能会存在这样的情况,返回的bean其实是个String,但是requiredType却传入Integer类型,那么这时候本步骤就会起作用了,它的功能是将返回的bean转换为requiredType所指定的类型。当然,String转换为Integer是最简单的一种转换,在Spring中提供了各种各样的转换器,用户也可以自己扩展转换器来满足需求。
- 将形参中传进来的name转换对应的beanName:String beanName = transformedBeanName(name);这个name有可能是FactoryBean对应的名字也有可能是别名(比如别名A指向名称为B的bean则返回B,别名A指向别名B,别名B又指向名称为C的bean则返回C)
到这里,天色渐暗…
BeanFactory接口说:一大堆XxxFactory,都跟我有关,我好累呀。
XmlBeanFactory争着说到:你还好,一次看不完看不明白,大不了日后有时间慢慢看,用到那个翻那个,慢慢的笔记就理解透了,你这最起码没人和你争风吃醋呀,说罢XmlBeanFactory就瞪向XmlBeanDefinitionReader
忽然,狂风大作,月色中,有一与BeanFactory样貌体型非常相似的人慢慢向他们三个走来…
未完待续…
巨人的肩膀:
(很多很多好的文章,特此感谢google以及B站各位前辈)
Spring源码深度解析