背景
上一篇我们介绍了自定义标签的解析,本篇我们介绍bean的加载
依旧是之前的测试方法
BeanFactory bf = new XmlBeanFactory(new ClassPathResource("beans.xml"));
User userTest = (User) bf.getBean("testBean");
System.out.println(userTest.getEmail());
对于bean的加载,在Spring中的调用为
User userTest = (User) bf.getBean("testBean");
1.加载流程
1.转换对应的beanName
传入的name可能是别名,也可能是FactoryBean,所以需要进行一系列的解析,包括
去除FactoryBean的修饰符,也就是说如果name="&aa",那么会首先去除&而使name="aa"
若指定alias所表示的最终beanName,例如别名A指向名称为B的bean,则返回B,若别名A指向别名B,别名B指向别名C,最终返回C
this.transformedBeanName(name);
2.尝试从缓存中加载单例
单例在Spring的同一个容器中只会被创建一次,后续再获取bean,就直接从单例缓存中获取了,当然这里也只是尝试加载,首先尝试从缓存加载,如果加载不成功则再次尝试从singletonFactories中加载,因为在创建单例bean的时候会存在依赖注入的情况,而在创建依赖的时候为例避免循环依赖,在Spring中创建bean的原则是不等bean创建完成就会将创建bean的ObjectFactory提早曝光加入到缓存中,一旦下一个bean创建的时候需要依赖上一个bean则直接使用ObjectFactory
this.getSingleton(beanName);
3.bean的实例化
如果从缓存中得到了bean的原始状态,则需要对bean进行实例化,这里必须强调,缓存中记录的只是最原始的bean状态,并不一定是我们要的最终bean,举个例子,加入我们需要对工厂bean进行处理,那么这里得到的其实是工厂bean的初始状态,但是我们真正需要的是工厂bean中定义的factory-method方法中返回的bean,而getObjecctForBeanInstance就是完成这个工作的。
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
4.原型模式的依赖检查
只有在单例模式下才会尝试解决循环依赖如果存在A中有B属性,B中有A属性,那么当依赖注入时,就会产生当A还未创建完成的时候,因为对于B的创建再次返回创建A,造成循环依赖,也就是说
idpRrototypeCurrentlyInCreation(beanName)判断true
5.检查parentBeanFactory
从代码上看,如果缓存没有数据的话,直接转到父类工厂上去加载了,
判断条件parentBeanFaactory!=null&&!containsBeanDefinition(beanName)
parentBeanFactory如果为空,则一切结束
!containsBeanDefinition(beanName)能检测到当前加载的XML配置文件中不包含beanName所对应的配置,就只能到parentBeanFactory去尝试,然后再递归调用getBean方法
6.将存储XML配置文件的GenericBeanDefinition转换为RootBeanDefinition
因为从XML配置文件中读取到的bean信息是存储在GenericBeanDefinition中的,但是所有的bean后续处理都是针对RootBeanDefinition的,所以在这里需要一个转换,转换的同时,如果有父类的bean不为空的话,则会一并合并父类属性
7.寻找依赖
因为bean初始化的过程很可能会用到某些属性,而某些属性很可能是动态配置的,且配置成依赖于其他其他的bean,那么在这个时候就必要先加载依赖的bean,所以在Spring的加载顺序中,初始化某一个bean的时候会先初始化这个bean对应的依赖
8.针对不同的scope进行bean创建
在Spring中存在不同的Scope,期中默认是singletion,但是还有些其他配置诸如prototype,request之类,在这个步骤 中,Spring会根据不同的配置进行不同的初始化策略
9.类型转换
程序到了这里返回bean后已经基本结束了,通常对该方法的调用参数requiredType是为空的,但是可能存在这样的情况,返回的bean实际是个String,但是requestType确传入Integer类型,那么这时候本步骤就会其作用了,它的功能是将返回的bean转换为requesType所指定的类型,Spring提供各种类型转换器
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}
2.执行doGetBean过程 doGetBean
package org.springframework.beans.factory.support;
public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport implements ConfigurableBeanFactory {
private final ThreadLocal<Object> prototypesCurrentlyInCreation =
new NamedThreadLocal<>("Prototype beans currently in creation");
/**
* Return an instance, which may be shared or independent, of the specified bean.
* @param name the name of the bean to retrieve
* @param requiredType the required type of the bean to retrieve
* @param args arguments to use when creating a bean instance using explicit arguments
* (only applied when creating a new instance as opposed to retrieving an existing one)
* @param typeCheckOnly whether the instance is obtained for a type check,
* not for actual use
* @return an instance of the bean
* @throws BeansException if the bean could not be created
* 返回一个实例,该实例可以是指定bean的共享或独立的。
* @param name要检索的bean的名称
* @param requiredType要检索的bean的必需类型
* @param args参数在使用显式参数创建bean实例时使用
*(仅适用于创建新实例而不是检索现有实例)
* @param typeCheckOnly是否获取实例用于类型检查,
* 不用于实际用途
* @返回bean的实例
* @throws BeansException如果无法创建bean
*/
@SuppressWarnings("unchecked")
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
//提取对应的beanName
final String beanName = transformedBeanName(name);
Object bean;
//检查缓存中或者实例工厂中是否有对应的实例
//在创建单例bean的时候存在依赖注入的情况,而在创建依赖的时候为了避免循环依赖,Spring创建bean的原则是不等bean创建完成的ObjectFactory提早曝光
//也就是将Objectactory加入到缓存中,一旦下一个bean创建的时候需要依赖上个bean则直接使用ObjectFactory
//直接尝试从缓存获取,或者singletonFactories中的ObjectFactory中取
// Eagerly check singleton cache for manually registered singletons.
Object sharedInstance = getSingleton(beanName);
//缓存中或者实例工厂中存在对应的实例
if (sharedInstance != null && args == null) {
if (logger.isDebugEnabled()) {
if (isSingletonCurrentlyInCreation(beanName)) {
logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +
"' that is not fully initialized yet - a consequence of a circular reference");
}
else {
logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
}
}
//返回对应的实例,有时候存在诸如BeanFactory的情况并不是直接返回实例本身而是返回指定方法返回的实例
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
//缓存中或者实例工厂中不存在对应的实例
else {
//只有在单例情况下才会尝试解决循环依赖,原型模式的情况下如果存在A中有B属性,B中有A属性,那么当依赖注入的时候,就会产生当A还未创建完成的时候因为对于B的创建再次返回A造成循环依赖,也就是如下情况
// Fail if we're already creating this bean instance:
// We're assumably within a circular reference.
if (isPrototypeCurrentlyInCreation(beanName)) {
//如果是Prototype(多例模式)并且bean正在创建中,如果是,说明存在循环依赖
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) {
return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
nameToLookup, requiredType, args, typeCheckOnly);
}
else if (args != null) {
//递归到BeanFactory中寻找
// Delegation to parent with explicit args.
return (T) parentBeanFactory.getBean(nameToLookup, args);
}
else {
// No args -> delegate to standard getBean method.
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
}
//如果不仅仅做类型检查则是创建bean,这里要进行记录
if (!typeCheckOnly) {
markBeanAsCreated(beanName);
}
try {
//将存储XML配置文件的GenericBeanDefinition转换为RootBeanDefinition,如果指定BeanName是子Bean的话同时会合并父类的相关属性
final 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);//在这里重新调用doGetBean方法,解析依赖的beanName即dep
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
}
}
}
//依赖为空
//实例化依赖的bean后便可实例化mbd本身了
//singletion单例模式的创建
// Create bean instance.
if (mbd.isSingleton()) {
//缓存中或者实例工厂中不存在对应的实例,需要创建bean
sharedInstance = getSingleton(beanName, () -> {
try {
//开始创建bean
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的实例化
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
//多例模式
else if (mbd.isPrototype()) {
// It's a prototype -> create a new instance.
//prototype模式的创建(new)
Object prototypeInstance = null;
try {
//创建前回调,标记bean正在创建中(set进ThreadLocal)
beforePrototypeCreation(beanName);
//创建bean
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
//创建bean后的回调,标记bean不在创建中(从ThreadLocal中移除)
afterPrototypeCreation(beanName);
}
//bean的实例化
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
else {
//指定的scope上实例化bean
String scopeName = mbd.getScope();
final 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, () -> {
//创建前回调,标记bean正在创建中(set进ThreadLocal)
beforePrototypeCreation(beanName);
try {
//创建bean
return createBean(beanName, mbd, args);
}
finally {
//创建bean后的回调,标记bean不在创建中(从ThreadLocal中移除)
afterPrototypeCreation(beanName);
}
});
//bean的实例化
bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
}
catch (IllegalStateException ex) {
throw new BeanCreationException(beanName,
"Scope '" + scopeName + "' is not active for the current thread; consider " +
"defining a scoped proxy for this bean if you intend to refer to it from a singleton",
ex);
}
}
}
catch (BeansException ex) {
cleanupAfterBeanCreationFailure(beanName);
throw ex;
}
}
// Check if required type matches the type of the actual bean instance.
//检查需要的类型是否符合bean的实际类型,将返回的bean转换为requesType所指定的类型
if (requiredType != null && !requiredType.isInstance(bean)) {
try {
T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
if (convertedBean == null) {
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
return convertedBean;
}
catch (TypeMismatchException ex) {
if (logger.isDebugEnabled()) {
logger.debug("Failed to convert bean '" + name + "' to required type '" +
ClassUtils.getQualifiedName(requiredType) + "'", ex);
}
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
}
return (T) bean;
}
2.1转换对应的beanName transformedBeanName
String beanName = this.transformedBeanName(name);
传入的name可能是别名,也可能是FactoryBean,所以需要进行一系列的解析,包括
去除FactoryBean的修饰符,也就是说如果name="&aa",那么会首先去除&而使name="aa"
若指定alias所表示的最终beanName,例如别名A指向名称为B的bean,则返回B,若别名A指向别名B,别名B指向别名C,最终返回C
/**
* Return the bean name, stripping out the factory dereference prefix if necessary,
* and resolving aliases to canonical names.
* @param name the user-specified name
* @return the transformed bean name
*/
protected String transformedBeanName(String name) {
return canonicalName(BeanFactoryUtils.transformedBeanName(name));
}
2.1.1去除FactoryBean的修饰符
String FACTORY_BEAN_PREFIX = "&";
/**
* Return the actual bean name, stripping out the factory dereference
* prefix (if any, also stripping repeated factory prefixes if found).
* @param name the name of the bean
* @return the transformed name
* @see BeanFactory#FACTORY_BEAN_PREFIX
* 返回实际的bean名称,删除工厂的取消引用
* 前缀(如果有的话,还会删除重复的工厂前缀(如果找到))。
* @param名称bean的名称
*/
public static String transformedBeanName(String name) {
Assert.notNull(name, "'name' must not be null");
String beanName = name;
while (beanName.startsWith(BeanFactory.FACTORY_BEAN_PREFIX)) {
beanName = beanName.substring(BeanFactory.FACTORY_BEAN_PREFIX.length());
}
return beanName;
}
2.1.2获取最终指向的beanName canonicalName
若指定alias所表示的最终beanName,例如别名A指向名称为B的bean,则返回B,若别名A指向别名B,别名B指向别名C,最终返回C
/**
* Determine the raw name, resolving aliases to canonical names.
* @param name the user-specified name
* @return the transformed name
* 确定原始名称,将别名解析为规范名称。
* @param name用户指定的名称
* @返回转换后的名称
*/
public String canonicalName(String name) {
String canonicalName = name;
// Handle aliasing...
String resolvedName;
do {
//获取canonicalName指向的Name,再将获取的Name赋值给canonicalName,循环直到返回最后的Name,aliasMap保存别名和实际内容直接的映射关系
//例:别名1 -> 别名2 别名2 -> 别名3 别名3 -> 实际bean,遍历aliasMap得到最终指向的beanName
resolvedName = this.aliasMap.get(canonicalName);
if (resolvedName != null) {
canonicalName = resolvedName;
}
}
while (resolvedName != null);
return canonicalName;
}
2.2尝试从缓存中加载单例 getSingleton
单例在Spring的同一个容器中只会被创建一次,后续再获取bean,就直接从单例缓存中获取了,当然这里也只是尝试加载,首先尝试从缓存加载,如果加载不成功则再次尝试从singletonFactories中加载,因为在创建单例bean的时候会存在依赖注入的情况,而在创建依赖的时候为例避免循环依赖,在Spring中创建bean的原则是不等bean创建完成就会将创建bean的ObjectFactory提早曝光加入到缓存中,一旦下一个bean创建的时候需要依赖上一个bean则直接使用ObjectFactory
Object sharedInstance = getSingleton(beanName);
@Override
@Nullable
public Object getSingleton(String beanName) {
//true表示允许早期依赖
return getSingleton(beanName, true);
}
这个方法从singletonObjects里获取实例,如果获取不到再从earlySingletonObjects里获取,如果还是获取不到再从singletonFactoies中获取baneName对应的ObjectFactory,然后调用ObjectFactory的getObject来创建bean并放到earlySingletonObjects中,并从singletonFactories里面remove掉这个ObjectFactory,而对后续的所有内存操作都是为了循环依赖检测时候使用,也就是在allowEarlyReference为true的情况下使用
package org.springframework.beans.factory.support;
public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {
//用于保存BeanName和创建bean实例之间的关系,beanName -> bean instance
private final Map<String, Object> singletonObjects = new ConcurrentHashMap(256);
//用于保存BeanName和创建bean工厂之间的关系,beanName -> ObjectFactory
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap(16);
//保存beanName和创建bean实例之间的关系,与singletonObjects不同的地方在于,当一个单例bean被放到这里面后,bean在创建过程中,可以通过getBean方法获取到,目的是用来检测循环引用
private final Map<String, Object> earlySingletonObjects = new HashMap(16);
//保存当前所有已注册的bean
private final Set<String> registeredSingletons = new LinkedHashSet(256);
/**
* Return the (raw) singleton object registered under the given name.
* <p>Checks already instantiated singletons and also allows for an early
* reference to a currently created singleton (resolving a circular reference).
* @param beanName the name of the bean to look for
* @param allowEarlyReference whether early references should be created or not
* @return the registered singleton object, or {@code null} if none found
* 返回以给定名称注册的(原始)单例对象。
* <p>检查已实例化的单例,并允许早期
* 引用当前创建的单例(解析循环引用)。
* @param beanName要查找的bean的名称
* @param allowEarlyReference 允许早期依赖
* @返回注册的单例对象;如果找不到,则返回{@code null}
*/
@Nullable
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
//检查缓存中是否存在实例
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
//如果为空,且正在创建中,锁定全局变量并进行处理
synchronized (this.singletonObjects) {
//如果bean正在加载则不处理
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
//当某些方法需要提前初始化的时候会调用addSingletonFactory方法将对于ObjectFactory初始化策略存储在singletonFactories
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
//调用预设的getObject方法
singletonObject = singletonFactory.getObject();
//记录在缓存中earlySingletonObjects和singletonFactories互斥
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
return singletonObject;
}
2.3缓存中存在,开始bean的实例化 getObjectForBeanInstance
如果从缓存中得到了bean的原始状态,则需要对bean进行实例化,这里必须强调,缓存中记录的只是最原始的bean状态,并不一定是我们要的最终bean,举个例子,加入我们需要对工厂bean进行处理,那么这里得到的其实是工厂bean的初始状态,但是我们真正需要的是工厂bean中定义的factory-method方法中返回的bean,而getObjecctForBeanInstance就是完成这个工作的。
- 对FactoryBean正确性的验证
- 对非FactoryBean不做处理
- 对bean进行转换
- 将Factory中解析bean的工作委托给getObjectFromFactoryBean
package org.springframework.beans.factory.support;
public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {
/**
* Get the object for the given bean instance, either the bean
* instance itself or its created object in case of a FactoryBean.
* @param beanInstance the shared bean instance
* @param name name that may include factory dereference prefix
* @param beanName the canonical bean name
* @param mbd the merged bean definition
* @return the object to expose for the bean
* 获取给定bean实例的对象,即bean
* 实例本身或其创建的对象(对于FactoryBean)。
* @param beanInstance共享bean实例
* @param名称可能包含工厂取消引用前缀的名称
* @param beanName规范的bean名称
* @param mbd合并的bean定义
* @返回对象以为bean公开
*/
protected Object getObjectForBeanInstance(
Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {
//如果指定的name是工厂相关(且&为前缀)且beanInstance又不是FactoryBean类型则验证不通过
// Don't let calling code try to dereference the factory if the bean isn't a factory.
if (BeanFactoryUtils.isFactoryDereference(name)) {
if (beanInstance instanceof NullBean) {
return beanInstance;
}
if (!(beanInstance instanceof FactoryBean)) {
throw new BeanIsNotAFactoryException(transformedBeanName(name), beanInstance.getClass());
}
}
// 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.
//现在有了bean的实例,这个实例可能会是正常的bean或者FactoryBean
//如果是FactoryBean我们使用它创建实例,但是如果用户想要直接获取工厂实例而不是工厂的getObject方法对应的实例那么传入的name应该加前缀&
if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {
return beanInstance;
}
//加载FactoryBean
Object object = null;
if (mbd == null) {
//尝试从缓存中加载bean
object = getCachedObjectForFactoryBean(beanName);
}
if (object == null) {
// Return bean instance from factory.
// 上面做过判断,如果不是FactoryBean就已经报错了,到这里确定beanInstance是FactoryBean类型
FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
// Caches object obtained from FactoryBean if it is a singleton.
// 将存储XML配置文件的GernericBeanDefinition转换为RootBeanDefinition,如果指定了BeanName是子Bean的话会合并父类相关属性
if (mbd == null && containsBeanDefinition(beanName)) {
mbd = getMergedLocalBeanDefinition(beanName);
}
//是否是用户定义而不是程序本身定义
boolean synthetic = (mbd != null && mbd.isSynthetic());
//从FactoryBean中解析Bean
object = getObjectFromFactoryBean(factory, beanName, !synthetic);
}
return object;
}
2.3.1验证FacoryBean的正确性 isFactoryDereference
String FACTORY_BEAN_PREFIX = "&";
/**
* Return whether the given name is a factory dereference
* (beginning with the factory dereference prefix).
* @param name the name of the bean
* @return whether the given name is a factory dereference
* @see BeanFactory#FACTORY_BEAN_PREFIX
*/
public static boolean isFactoryDereference(@Nullable String name) {
return (name != null && name.startsWith(BeanFactory.FACTORY_BEAN_PREFIX));
}
2.3.2从缓存中加载bean,方法为父类FactoryBeanRegistrySupport中的方法 getCachedObjectForFactoryBean
/**
* Obtain an object to expose from the given FactoryBean, if available
* in cached form. Quick check for minimal synchronization.
* @param beanName the name of the bean
* @return the object obtained from the FactoryBean,
* or {@code null} if not available
*/
@Nullable
protected Object getCachedObjectForFactoryBean(String beanName) {
return this.factoryBeanObjectCache.get(beanName);
}
2.3.3从FactoryBean中解析Bean getObjectFromFactoryBean
实现了doGetObjectFromFactoryBean中的方法后并没有直接返回,而是根据shouldPostProcess调用ObjectFactory的后处理器
/**
* Obtain an object to expose from the given FactoryBean.
* @param factory the FactoryBean instance
* @param beanName the name of the bean
* @param shouldPostProcess whether the bean is subject to post-processing
* @return the object obtained from the FactoryBean
* @throws BeanCreationException if FactoryBean object creation failed
* @see org.springframework.beans.factory.FactoryBean#getObject()
* 从给定的FactoryBean获取要暴露的对象。
* @param工厂的FactoryBean实例
* @param beanName bean的名称
* @param shouldPostProcess Bean是否要进行后处理
* @返回从FactoryBean获得的对象
* 如果FactoryBean对象创建失败,则@@ throws BeanCreationException
* @see org.springframework.beans.factory.FactoryBean#getObject()
*/
protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {
if (factory.isSingleton() && containsSingleton(beanName)) {
//单例模式 双重检测
synchronized (getSingletonMutex()) {
//从缓存中获取,如果object不为null,执行下去直接返回object
Object object = this.factoryBeanObjectCache.get(beanName);
//如果获取的对象object为null
if (object == null) {
//根据FactoryBean获取对象
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)
//仅对上面的getObject()调用期间尚未进行的后处理和存储进行存储
//(例如,由于自定义getBean调用触发了循环引用处理)
//如果此时可以根据缓存获取到对象,就使用根据缓存获取到的
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;
}
}
2.3.3.1执行从FactoryBean中解析Bean doGetObjectFromFactoryBean
如果bean声明类型为FactoryBean类型,则当提取bean时提取的不是FactoryBean,而是FactoryBean对应的getObejct方法返回的bean
/**
* Obtain an object to expose from the given FactoryBean.
* @param factory the FactoryBean instance
* @param beanName the name of the bean
* @return the object obtained from the FactoryBean
* @throws BeanCreationException if FactoryBean object creation failed
* @see org.springframework.beans.factory.FactoryBean#getObject()
* 从给定的FactoryBean获取要暴露的对象。
* @param工厂的FactoryBean实例
* @param beanName bean的名称
* @返回从FactoryBean获得的对象
*如果FactoryBean对象创建失败,则@@ throws BeanCreationException
* @see org.springframework.beans.factory.FactoryBean#getObject()
*/
private Object doGetObjectFromFactoryBean(final FactoryBean<?> factory, final 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;
}
调用ObjectFactory的后处理器
2.4缓存中不存在,重新开始bean的加载 getSingleton
之前讲了如何从缓存中加载单例bean,但是如果缓存中不存在,就需要重新开始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; } });
使用重载(方法名相同,参数不同)的方法实现bean的加载
以下代码实际上是在单例创建前后做一些准备和处理操作,真正的获取单例bean的方法是在singletonFactory.getObject();中实现的,代码包括以下内容
1.检查缓存是否加载过
2.如果没有加载,记录beanName的正在加载状态
3.加载单例前记录加载状态
4.通过调用参数传入的ObjectFactory的个体Object方法实例化bean
5.加载单例后的处理方法调用
6.将结果记录至缓存并删除加载bean过程中记录的所有辅助状态
7.返回处理结果
package org.springframework.beans.factory.support;
public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {
/**
* Return the (raw) singleton object registered under the given name,
* creating and registering a new one if none registered yet.
* @param beanName the name of the bean
* @param singletonFactory the ObjectFactory to lazily create the singleton
* with, if necessary
* @return the registered singleton object
* 返回以给定名称注册的(原始)单例对象,
* 创建并注册一个新的(如果尚未注册)。
* @param beanName bean的名称
* @param singletonFactory用于延迟创建单例的ObjectFactory
* 与(如果需要)
* @返回注册的单例对象
*/
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) {
//为空才进行singleton的初始化
if (this.singletonsCurrentlyInDestruction) {
//如果beanName正在创建中
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) {
//如果是新的单例bean,就加入缓存,将结果记录至缓存并删除家长在bean过程中各种辅助状态
addSingleton(beanName, singletonObject);
}
}
return singletonObject;
}
}
/**
* Register an Exception that happened to get suppressed during the creation of a
* singleton bean instance, e.g. a temporary circular reference resolution problem.
* @param ex the Exception to register
* 注册一个在创建过程中被抑制的异常
* 单例bean实例,例如 临时循环参考解析问题。
* @param例外注册
*/
protected void onSuppressedException(Exception ex) {
synchronized (this.singletonObjects) {
if (this.suppressedExceptions != null) {
this.suppressedExceptions.add(ex);
}
}
}
2.4.1单例创建前的操作 beforeSingletonCreation
beforeSingletonCreation(beanName);
/** Names of beans that are currently in creation 正在创建的bean名称*/
private final Set<String> singletonsCurrentlyInCreation =
Collections.newSetFromMap(new ConcurrentHashMap<>(16));
/** Names of beans currently excluded from in creation checks 排除校验的bean名称 */
private final Set<String> inCreationCheckExclusions =
Collections.newSetFromMap(new ConcurrentHashMap<>(16));
/**
* Callback before singleton creation.
* <p>The default implementation register the singleton as currently in creation.
* @param beanName the name of the singleton about to be created
* @see #isSingletonCurrentlyInCreation
*/
protected void beforeSingletonCreation(String beanName) {
//将正要创建的bean记录在缓存中,这样可以进行循环依赖检测
//如果inCreationCheckExclusions不包含beanName且singletonsCurrentlyInCreation新增失败,set无法新增已存在的对象
if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
}
2.4.2创建bean操作 createBean
bean的加载逻辑实际是在传入的ObjectFactory类型的参数singletonFactory中定义的,实际只是调用了createBean方法
之前讲了如何从缓存中加载单例bean,但是如果缓存中不存在,就需要重新开始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; } });
1.根据设置的class属性或者根据className解析class
2.对override属性进行标记及验证
在Spring中存在lookuo-method和replace-method,这两个配置的加载是将配置统一存放在BeanDefinition中的methodOverrides属性里,而这个函数的操作也是针对这两个配置的
3.应用初始化前的后处理器,解析指定bean是否存在初始化前的短路操作
4.创建bean
package org.springframework.beans.factory.support;
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
implements AutowireCapableBeanFactory {
/**
* Central method of this class: creates a bean instance,
* populates the bean instance, applies post-processors, etc.
* @see #doCreateBean
*/
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
if (logger.isDebugEnabled()) {
logger.debug("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.
// 确保此时确实解析了bean类,并且
// 在动态解析的类的情况下克隆bean定义
// 无法存储在共享的合并bean定义中。
// 反射解析bean类
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一个机会来返回代理来替代真正的实例
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
//短路判断,如果经过前置处理后的返回结果不为空,会直接忽略后续的bean而直接返回,AOP就是基于这里判断的
if (bean != null) {
return bean;
}
}
catch (Throwable ex) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
"BeanPostProcessor before instantiation of bean failed", ex);
}
try {
//创建bean
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isDebugEnabled()) {
logger.debug("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);
}
}
2.4.2.1处理override属性 prepareMethodOverrides
mbdToUse.prepareMethodOverrides();
之前提到过,在Spring中配置了lookup-method和replace-method这两个配置功能,这两个配置其实就是将配置统一存放在BeanDefinition中的methodOverrides属性里,这两个功能的实现原理是在bean实例化的时候如果检测到存在methodOverrides属性,会动态的为当前bean生成代理并使用对应的拦截器为bean做增强处理,相关逻辑实现在bean的实例化部分介绍
对于方法的匹配来说,如果一个类中存在若干个重载的方法,那么在函数调用及增强的时候需要根据参数类型进行匹配,来确认最终调用的是哪个函数,但是Spring将一部分匹配工作在这里完成了,如果对应类中的对应方法名个数为1,就可以直接找到对应的方法,而不需要进行匹配参数的认证,还可以提前对方法的存在进行验证
/**
* Validate and prepare the method overrides defined for this bean.
* Checks for existence of a method with the specified name.
* @throws BeanDefinitionValidationException in case of validation failure
* 验证并准备为此bean定义的方法替代。
* 检查是否存在具有指定名称的方法。
* @如果验证失败,则抛出BeanDefinitionValidationException
*/
public void prepareMethodOverrides() throws BeanDefinitionValidationException {
// Check that lookup methods exists.
if (hasMethodOverrides()) {
Set<MethodOverride> overrides = getMethodOverrides().getOverrides();
synchronized (overrides) {
for (MethodOverride mo : overrides) {
prepareMethodOverride(mo);
}
}
}
}
/**
* Validate and prepare the given method override.
* Checks for existence of a method with the specified name,
* marking it as not overloaded if none found.
* @param mo the MethodOverride object to validate
* @throws BeanDefinitionValidationException in case of validation failure
* 验证并准备给定的方法重写。
* 检查是否存在具有指定名称的方法,
* 如果未找到,则将其标记为未过载。
* @param mo MethodOverride对象进行验证
* @如果验证失败,则抛出BeanDefinitionValidationException
*/
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) {
// Mark override as not overloaded, to avoid the overhead of arg type checking.
//标记MethodOverride暂时未被覆盖,避免参数类型检查的开销
mo.setOverloaded(false);
}
}
2.4.2.2实例化的前置处理 resolveBeforeInstantiation
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
在真正调用doCreate方法创建bean的实例前使用了这样一个方法resolveBeforeInstantiation(beanName,mbd)对BeanDefinigiton中的属性做了前置处理,如果前置处理的结果不为空,会直接忽略后续Bean的创建而直接返回结果
/**
* Apply before-instantiation post-processors, resolving whether there is a
* before-instantiation shortcut for the specified bean.
* @param beanName the name of the bean
* @param mbd the bean definition for the bean
* @return the shortcut-determined bean instance, or {@code null} if none
* 应用实例化后处理器,以解决是否存在
* 指定bean的实例化前快捷方式。
* @param beanName bean的名称
* @param mbd bean的bean定义
* @返回快捷方式确定的bean实例;如果没有,则返回{@code null}
*/
@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;
}
2.4.2.3实例化前的后处理器调用 applyBeanPostProcessorsBeforeInstantiation
bean的实例化调用,也就是将AbstractBeanDefinition转换为BeanWapper前的处理,给子类一个修改BeanDefinition的机会,也就是当程序经过这个方法后,bean已经不是我们认为的bean了,而是成为了一个经过处理的代理bean,可能是通过cglib生成,也可能是通过其他技术生成的,bean实例化前后会调用后处理器的方法进行处理
/**
* Apply InstantiationAwareBeanPostProcessors to the specified bean definition
* (by class and name), invoking their {@code postProcessBeforeInstantiation} methods.
* <p>Any returned object will be used as the bean instead of actually instantiating
* the target bean. A {@code null} return value from the post-processor will
* result in the target bean being instantiated.
* @param beanClass the class of the bean to be instantiated
* @param beanName the name of the bean
* @return the bean object to use instead of a default instance of the target bean, or {@code null}
* @see InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation
* 将InstantiationAwareBeanPostProcessors应用于指定的bean定义
*(按类和名称),调用其{@code postProcessBeforeInstantiation}方法。
* <p>任何返回的对象都将用作bean,而不是实际实例化
* 目标bean。 后处理器的{@code null}返回值将
* 导致目标bean被实例化。
* @param beanClass要实例化的bean的类
* @param beanName bean的名称
* @返回要使用的bean对象,而不是目标bean的默认实例,或者{@code null}
* @see InstantiationAwareBeanPostProcessor#
*/
@Nullable
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
if (result != null) {
return result;
}
}
}
return null;
}
循环依赖
2.4.2.4创建bean doCreateBean
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
常规bean的创建操作在此完成
package org.springframework.beans.factory.support;
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
implements AutowireCapableBeanFactory {
/**
* Actually create the specified bean. Pre-creation processing has already happened
* at this point, e.g. checking {@code postProcessBeforeInstantiation} callbacks.
* <p>Differentiates between default bean instantiation, use of a
* factory method, and autowiring a constructor.
* @param beanName the name of the bean
* @param mbd the merged bean definition for the bean
* @param args explicit arguments to use for constructor or factory method invocation
* @return a new instance of the bean
* @throws BeanCreationException if the bean could not be created
* @see #instantiateBean
* @see #instantiateUsingFactoryMethod
* @see #autowireConstructor
* 实际创建指定的bean。 预创建处理已经发生
* 在这一点上,例如 检查{@code postProcessBeforeInstantiation}回调。
* <p>区分默认的bean实例化,使用
* 工厂方法,并自动装配构造函数。
* @param beanName bean的名称
* @param mbd该bean的合并bean定义
* @param args用于构造函数或工厂方法调用的显式参数
* @返回bean的新实例
* @throws BeanCreationException如果无法创建bean
* @请参阅#instantiateBean
* @see #instantiateUsingFactoryMethod
* @请参阅#autowireConstructor
*/
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
// Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
//从缓存中移除bean,因为要创建新的bean了
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
//根据指定bean的使用策略创建新的实例,如:工厂方法,构造函数自动注入,简单初始化
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
final Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
// Allow post-processors to modify the merged bean definition.
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing of merged bean definition failed", ex);
}
mbd.postProcessed = true;
}
}
// Eagerly cache singletons to be able to resolve circular references
// even when triggered by lifecycle interfaces like BeanFactoryAware.
//是否需要提早曝光:单例&允许循环依赖&当前bean正在创建中,检测循环依赖
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isDebugEnabled()) {
logger.debug("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
//为避免后期循环依赖,可以在bean初始化完成前将创建实例的ObjectFactory加入工厂,其他bean引用此bean时直接从ObjectFactory获取bean
//getEarlyBeanReference对bean再一次依赖引用,主要应用SmartInstantiationAware BeanPost Processor其中我们熟悉的AOP就是在这里将advance动态织入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不为空则表示当前bean创建后其依赖的bean却没有创建完,也就是存在循环依赖
if (!actualDependentBeans.isEmpty()) {
throw new BeanCurrentlyInCreationException(beanName,
"Bean with name '" + beanName + "' has been injected into other beans [" +
StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
"] in its raw version as part of a circular reference, but has eventually been " +
"wrapped. This means that said other beans do not use the final version of the " +
"bean. This is often the result of over-eager type matching - consider using " +
"'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
}
}
}
}
// Register bean as disposable.
try {
//根据scopse注册bean
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
}
整个程序的思路
1.如果是单例需要先清除缓存
2.实例化bean,将BeanDefinition转换为BeanWrapper
转换是一个复杂的过程
- 如果存在工厂方法则使用工厂方法进行初始化
- 一个类有多个构造函数,每个构造函数都有不同的参数,所以需要根据参数锁定构造函数并进行初始化
- 如果既不存在工厂方法也不存在带有参数的构造函数,则使用默认的构造函数进行bean的初始化
3.MergedBeanDefinitionPostProcessor的应用
bean合并后的处理,Autowired注解正是通过此方法实现诸如类型的预解析
4.依赖处理
在Spring中会有循环依赖的情况,例如A中存在B的属性,而B中又存在A的属性,这样会构成一个循环依赖,此时如果A和B都是单例,那么在Spring中的处理方式就是当创建B的时候,涉及自动注入A的步骤时,并不是直接去创建A,而是通过放入缓存中的ObjectFactory来创建实例,这样就解决了循环依赖的问题
5.属性填充,将所有属性填充置bean的实例中
6.循环依赖检查
之前有提到过,在Spring中解决循环依赖只针对单例有效,而对于prototype的bean,Spring没有好的解决方法,唯一要做的就是抛出异常,这个步骤会检查以及加载的bean是否已经出现了依赖循环,并判断是否需要抛出异常
7.注册DisposableBean
如果配置了destroy-method,这里需要注册以便于在销毁时调用
8.完成创建步骤并返回
创建bean的实例
2.4.2.4.1创建bean实例createBeanInstance
/**
* Create a new instance for the specified bean, using an appropriate instantiation strategy:
* factory method, constructor autowiring, or simple instantiation.
* @param beanName the name of the bean
* @param mbd the bean definition for the bean
* @param args explicit arguments to use for constructor or factory method invocation
* @return a BeanWrapper for the new instance
* @see #obtainFromSupplier
* @see #instantiateUsingFactoryMethod
* @see #autowireConstructor
* @see #instantiateBean
* 使用适当的实例化策略为指定的bean创建一个新实例:
* 工厂方法,构造函数自动装配或简单实例化。
* @param beanName bean的名称
* @param mbd bean的bean定义
* @param args用于构造函数或工厂方法调用的显式参数
* @返回新实例的BeanWrapper
* @请参阅#obtainFromSupplier
* @see #instantiateUsingFactoryMethod
* @请参阅#autowireConstructor
* @请参阅#instantiateBean
*/
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
// Make sure bean class is actually resolved at this point.
//反射解析class
Class<?> beanClass = resolveBeanClass(mbd, beanName);
//beanClass需要时public的
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());
}
//从给的的提供者获取bean实例
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);
}
}
// Need to determine the constructor...
//需要根据参数解析构造函数
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null ||
mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
//构造函数自动注入
return autowireConstructor(beanName, mbd, ctors, args);
}
// No special handling: simply use no-arg constructor.
//使用默认构造函数构造
return instantiateBean(beanName, mbd);
}
1.如果在RootBeanDefinition中存在factoryMethodName属性,或者在配置文件中配置了factory-method方法,那么Spring会尝试使用instantiateUsingFactoryMethod(beanName, mbd, args)方法根据RootBeanDefinition中的配置生成bean的实例
2.解析构造函数并进行构造函数的初始化,因为每个bean对应的类中可能有多个构造函数,而每个构造函数的参数不同,Spring在根据参数及类型取判断最终会使用哪个构造函数进行实例化,但是,判断的过程是个比较消耗性能的步骤,所以采用缓存机制,如果已经解析过了就不再重复解析,而是直接从RootBeanDefinition中的属性reslovedConstructorOfFactoryMethod缓存的值去取,否则需要再次解析,并将解析的结果添加到RootBeanDefinition的属性reslovedConstructorOrFactoryMethod中
2.4.2.4.2带参数的构造函数实例化过程utowireConstructor
对于实例的创建Spring中分了两种情况,一种是通用的实例化,另一种是带有参数的实例化,带有参数的实例化相当复杂,因为存在不确定性,所以在对应参数判断上有大量工作
/**
* "autowire constructor" (with constructor arguments by type) behavior.
* Also applied if explicit constructor argument values are specified,
* matching all remaining arguments with beans from the bean factory.
* <p>This corresponds to constructor injection: In this mode, a Spring
* bean factory is able to host components that expect constructor-based
* dependency resolution.
* @param beanName the name of the bean
* @param mbd the bean definition for the bean
* @param ctors the chosen candidate constructors
* @param explicitArgs argument values passed in programmatically via the getBean method,
* or {@code null} if none (-> use constructor argument values from bean definition)
* @return a BeanWrapper for the new instance
* “自动装配构造函数”(按类型带有构造函数参数)的行为。
* 如果指定了显式构造函数参数值,则同样适用
* 将所有剩余的参数与bean工厂中的bean匹配。
* <p>这对应于构造函数注入:在这种模式下,一个Spring
* bean factory能够托管期望基于构造函数的组件
* 依赖关系解析。
* @param beanName bean的名称
* @param mbd bean的bean定义
* @param约束所选的候选构造函数
* @paramexplicitArgs参数值通过getBean方法以编程方式传递,
* 或{@code null}(如果没有)(->使用bean定义中的构造函数参数值)
* @返回新实例的BeanWrapper
*/
protected BeanWrapper autowireConstructor(
String beanName, RootBeanDefinition mbd, @Nullable Constructor<?>[] ctors, @Nullable Object[] explicitArgs) {
return new ConstructorResolver(this).autowireConstructor(beanName, mbd, ctors, explicitArgs);
}
package org.springframework.beans.factory.support;
/**
* "autowire constructor" (with constructor arguments by type) behavior.
* Also applied if explicit constructor argument values are specified,
* matching all remaining arguments with beans from the bean factory.
* <p>This corresponds to constructor injection: In this mode, a Spring
* bean factory is able to host components that expect constructor-based
* dependency resolution.
* @param beanName the name of the bean
* @param mbd the merged bean definition for the bean
* @param chosenCtors chosen candidate constructors (or {@code null} if none)
* @param explicitArgs argument values passed in programmatically via the getBean method,
* or {@code null} if none (-> use constructor argument values from bean definition)
* @return a BeanWrapper for the new instance
* “自动装配构造函数”(按类型带有构造函数参数)的行为。
* 如果指定了显式构造函数参数值,则同样适用
* 将所有剩余的参数与bean工厂中的bean匹配。
* <p>这对应于构造函数注入:在这种模式下,一个Spring
* bean factory能够托管期望基于构造函数的组件
* 依赖关系解析。
* @param beanName bean的名称
* @param mbd该bean的合并bean定义
* @param selectedCtors选择了候选构造函数(如果没有,则为{@code null})
* @paramexplicitArgs参数值通过getBean方法以编程方式传递,
* 或{@code null}(如果没有)(->使用bean定义中的构造函数参数值)
* @返回新实例的BeanWrapper
*/
public BeanWrapper autowireConstructor(final String beanName, final RootBeanDefinition mbd,
@Nullable Constructor<?>[] chosenCtors, @Nullable final 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) {
// Found a cached constructor...
//从缓存中获取的可能是初始的参数也可能是最终的参数,需要经过类型转换器过滤,保证类型对应
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) {
// Need to resolve the constructor.
//是否自动注入
boolean autowiring = (chosenCtors != null ||
mbd.getResolvedAutowireMode() == RootBeanDefinition.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);
}
// 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);
}
}
//排序给定的构造函数,public构造函数优先排列,按照构造函数数量降序,然后是非public构造函数,按照后遭函数数量降序
AutowireUtils.sortConstructors(candidates);
int minTypeDiffWeight = Integer.MAX_VALUE;
Set<Constructor<?>> ambiguousConstructors = null;
LinkedList<UnsatisfiedDependencyException> causes = null;
for (Constructor<?> candidate : candidates) {
Class<?>[] paramTypes = candidate.getParameterTypes();
if (constructorToUse != null && argsToUse.length > paramTypes.length) {
// Already found greedy constructor that can be satisfied ->
// do not look any further, there are only less greedy constructors left.
//如果已经找到选用的构造函数或者需要的参数个数小于当前的构造函数参数个数则终止,因为已经按照参数个数降序排列
break;
}
if (paramTypes.length < minNrOfArgs) {
//参数个数不相等
continue;
}
ArgumentsHolder argsHolder;
if (resolvedValues != null) {
//有参数则根据参数值构造对应参数类型的参数
try {
//注释上获取参数名称
String[] paramNames = ConstructorPropertiesChecker.evaluate(candidate, paramTypes.length);
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);
}
catch (UnsatisfiedDependencyException ex) {
if (this.beanFactory.logger.isTraceEnabled()) {
this.beanFactory.logger.trace(
"Ignoring constructor [" + candidate + "] of bean '" + beanName + "': " + ex);
}
// Swallow and try next constructor.
if (causes == null) {
causes = new LinkedList<>();
}
causes.add(ex);
continue;
}
}
else {
// Explicit arguments given -> arguments length must match exactly.
if (paramTypes.length != explicitArgs.length) {
continue;
}
//构造函数没有参数的情况下
argsHolder = new ArgumentsHolder(explicitArgs);
}
//检测是否有不确定性的构造函数存在,例如不同构造函数的参数为父子类型
int typeDiffWeight = (mbd.isLenientConstructorResolution() ?
argsHolder.getTypeDifferenceWeight(paramTypes) : argsHolder.getAssignabilityWeight(paramTypes));
// Choose this constructor if it represents the closest match.
//如果它代表着当前最接近的匹配则选择作为构造函数
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.storeCache(mbd, constructorToUse);
}
}
try {
final InstantiationStrategy strategy = beanFactory.getInstantiationStrategy();
Object beanInstance;
if (System.getSecurityManager() != null) {
final Constructor<?> ctorToUse = constructorToUse;
final Object[] argumentsToUse = argsToUse;
beanInstance = AccessController.doPrivileged((PrivilegedAction<Object>) () ->
strategy.instantiate(mbd, beanName, beanFactory, ctorToUse, argumentsToUse),
beanFactory.getAccessControlContext());
}
else {
beanInstance = strategy.instantiate(mbd, beanName, this.beanFactory, constructorToUse, argsToUse);
}
//将构建的实例加入BeanWrapper中
bw.setBeanInstance(beanInstance);
return bw;
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Bean instantiation via constructor failed", ex);
}
}
构造函数参数的确定
根据explicitArgs参数判断
如果传入放入参数explicitArgs不为空,就可以直接确定参数,因为explicitArgs参数是在调用Bean的时候用户指定的,在BeanFactory类中存在这样的方法
Object getBean(String name,Object ...args) throws BeansException;
在获取bean的时候,用户不但可以指定bean的名称还可以指定bean所对应类的构造函数或者工厂方法的参数,主要用于静态工厂方法的调用,而这里是需要给定完全匹配的参数的,所以,便可以判断,如过传入参数explicitArgs不为空,则可以确定构造函数就是它
从缓存中获取
除此之外,确定参数的办法如果之前已经分析过,也就是说构造函数参数已经记录在缓存中,那么便可以直接拿来使用,而且在缓存中缓存的可能是参数的最终类型也可能是参数的初始类型,例如构造函数要求int类型,原始参数可能是String类型的"1",那么即使在缓存中得到了参数,也需要经过类型转换器的过滤以保证参数类型和构造器参数类型完全匹配
配置文件获取
如果不能根据传入参数explicitArgs确定构造函数的参数也无法在缓存中得到相关信息,就只能开始新一轮分析了,分析从获取,分析从获取配置文件中配置的构造函数信息开始,经过之前的分析,我们知道,Spring中配置文件中的信息经过转换都会通过BeanDefinition实例承载,也就是参数mbd中包含,那么可以通过调用mdb.getConstructorArgumentValues()来获取配置的构造函数信息,有了配置中的信息便可以获取对应的参数信息了,获取参数值信息包括直接指定值,如:直接指定构造函数中某个值为原始类型String类型,或者是一个对其它bean的引用,而这一处理委托给resloveConstructorArguments方法,并返回能解析到的参数个数
构造函数的确定
经过第一步后已经确定构造函数的参数,结下来的任务就是根据构造函数参数在所构造函数中锁定对应的构造函数,而匹配的方法就是根据参数个数匹配,所以在匹配之前需要先对 构造函数按照public构造函数优先参数数量降序,非public构造函数参数数量降序,这样可以在遍历的情况下迅速判断排在后面的构造函数参数个数是否符合条件,由于在配置文件中并不是唯一限制使用参数位置索引的方式去创建,同样还支持指定参数名称进行设置参数值的情况,如<constructor-arg name="aa">,那么这种情况就需要首先确定构造函数中的参数名称
获取构造函数中参数名称的方式有两种,一种是通过注解的方式直接获取,另一种就是使用Spring中提供的工具类ParameterNameDiscoverer来获取,构造函数,参数名称,参数类型,参数值都后就可以锁定构造函数以及转换对应的参数类型了
根据确定的构造函数转换对应的参数类型,主要使用Spring中提供的类型转换器或者用户提供的自定义准换器进行准换
构造函数不确定性单验证
有时候即使构造函数,参数名称,参数类型,参数值都确定了也不一定会直接锁定构造函数,不同的构造函数参数为父子关系,所以Spring在最后又做了一次验证
根据实例化策略以及得到的构造函数以及构造函数参数实例化bean
2.4.2.4.3不带参数的构造函数实例化过程 instantiateBean
/**
* Instantiate the given bean using its default constructor.
* @param beanName the name of the bean
* @param mbd the bean definition for the bean
* @return a BeanWrapper for the new instance
* 使用其默认构造函数实例化给定的bean。
* @param beanName bean的名称
* @param mbd bean的bean定义
* @返回新实例的BeanWrapper
*/
protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
try {
Object beanInstance;
final BeanFactory parent = this;
if (System.getSecurityManager() != null) {
beanInstance = AccessController.doPrivileged((PrivilegedAction<Object>) () ->
getInstantiationStrategy().instantiate(mbd, beanName, parent),
getAccessControlContext());
}
else {
beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
}
BeanWrapper bw = new BeanWrapperImpl(beanInstance);
initBeanWrapper(bw);
return bw;
}
catch (Throwable ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
}
}
2.4.2.4.4实例化策略 instantiate
instantiate(mbd, beanName, parent)
如果判断bd.hasMethodOverrides()为空,也就是用户没有使用replace或者lookup配置方法,那么直接使用反射的方式,但是如果使用了这两个特效,在直接使用反射就不合适了,因为需要将这两个配置提供的功能切入进去,所以必须要使用动态代理的方式将包含这俩个特性的所对应的逻辑的拦截增强器设置进去,这样才可以保证在调用方法的时候会被相应的拦截器增强,返回值为包含拦截器的代理实例
package org.springframework.beans.factory.support;
public class SimpleInstantiationStrategy implements InstantiationStrategy {
@Override
public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
// Don't override the class with CGLIB if no overrides.
//如果有需要覆盖或者动态替换的方法则需要使用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);
}
}
package org.springframework.beans.factory.support;
public class CglibSubclassingInstantiationStrategy extends SimpleInstantiationStrategy {
/**
* Create a new instance of a dynamically generated subclass implementing the
* required lookups.
* @param ctor constructor to use. If this is {@code null}, use the
* no-arg constructor (no parameterization, or Setter Injection)
* @param args arguments to use for the constructor.
* Ignored if the {@code ctor} parameter is {@code null}.
* @return new instance of the dynamically generated subclass
*/
public Object instantiate(@Nullable Constructor<?> ctor, @Nullable Object... args) {
Class<?> subclass = createEnhancedSubclass(this.beanDefinition);
Object instance;
if (ctor == null) {
instance = BeanUtils.instantiateClass(subclass);
}
else {
try {
Constructor<?> enhancedSubclassConstructor = subclass.getConstructor(ctor.getParameterTypes());
instance = enhancedSubclassConstructor.newInstance(args);
}
catch (Exception ex) {
throw new BeanInstantiationException(this.beanDefinition.getBeanClass(),
"Failed to invoke constructor for CGLIB enhanced subclass [" + subclass.getName() + "]", ex);
}
}
// SPR-10785: set callbacks directly on the instance instead of in the
// enhanced class (via the Enhancer) in order to avoid memory leaks.
Factory factory = (Factory) instance;
factory.setCallbacks(new Callback[] {NoOp.INSTANCE,
new LookupOverrideMethodInterceptor(this.beanDefinition, this.owner),
new ReplaceOverrideMethodInterceptor(this.beanDefinition, this.owner)});
return instance;
}
2.4.2.4.4记录创建bean的ObjectFactory addSingletonFactory
earlySingletonExposure:是提早曝光的单例
mbd.isSingleton():代表是否是单例
this.allowCircularReferences:是否允许循环依赖,在配置文件中并没有参数配置,可以通过硬编码或者自定义命名空间进行配置
isSingletonCurrentlyInCreation(beanName):该bean是否在创建中,在Spring中,会有专门的属性默认为DefaultSingletonBeanRegistry的singletonsCurrentlyInCreation来记录bean的加载状态,在bean开始创建前会将beanName记录在属性中,在bean创建结束后会将beanName从属性中移除,不同scope的位置记录不一样,我们以singleton为例子,在singleton下记录属性的位置在DefaultSingleBeanRegistry类的public Object getSingleton(String beanName,ObjectFctory singletonFactory)函数的beforeSingleCreation(beanName)和afterSingleCreation(beanName)中,在这两段函数中分别this.singletonsCurrentlyInCreation.add(beanName)和this.singletonsCurrentlyInCreation.remove(beanName)
package org.springframework.beans.factory.support;
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
implements AutowireCapableBeanFactory {
// 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.isDebugEnabled()) {
logger.debug("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
/**
* Add the given singleton factory for building the specified singleton
* if necessary.
* <p>To be called for eager registration of singletons, e.g. to be able to
* resolve circular references.
* @param beanName the name of the bean
* @param singletonFactory the factory for the singleton object
*/
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);
}
}
}
经过以上分析,我们知道earlySingletonExposure要满足是否是否单例,是否循环依赖,是否对应的bean正在创建,三个条件都满足时才会执行addSingletonFactory操作
加入SingletonFactory的作用
以AB循环依赖为例,类A中含有属性B,而B中也有属性A,初始化过程如下
创建A的时候会记录A所对应的beanNam,并将beanA的创建工厂加入缓存中,在对A的属性进行调用也就是调用populate方法的时候又会再一次对B进行递归创建,同样的因为B中同样存在A属性,因此在实例化B的populate方法中,又会再次初始化A,也就是图中最后,调用getBean(A),关建在于,这个函数并不是直接实例化A,而是去检测缓存中是否有一经创建好的对应bean,或者是否已经创建号的ObjectFactory,而此时对于A的ObjectFactory我们早已创建,所以不会再向后执行,而是直接调用ObjectFactory创建A,,这里最关键的是ObjectFactory的实现
/**
* Obtain a reference for early access to the specified bean,
* typically for the purpose of resolving a circular reference.
* @param beanName the name of the bean (for error handling purposes)
* @param mbd the merged bean definition for the bean
* @param bean the raw bean instance
* @return the object to expose as bean reference
* 获得早期访问指定bean的参考,
* 通常用于解决循环引用的目的。
* @param beanName bean的名称(用于错误处理)
* @param mbd该bean的合并bean定义
* @param bean原始bean实例
* @返回对象公开为bean引用
*/
protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
Object exposedObject = bean;
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
}
}
}
return exposedObject;
}
在getEarlyBeanReference函数中并没有太多的处理逻辑,或者除了后处理器调用外没有别的工作,根据以上分析,基本可以理清楚Spring处理循环依赖的方法,在B中创建依赖A时通过ObjectFactory提供的实例化方法来中断A的属性填充,使B中持有的A仅仅是刚开始初始化并没有填充任何属性的A,而初始化A的步骤还是在最开始创建A的时候进行的,但是因为A和B中的A所表示的属性地址是一样的,所以在A中创建好的属性填充可以通B中的A获取这样就解决了循环依赖问题
2.4.2.4.5属性注入 populateBean
populateBean(beanName, mbd, instanceWrapper);
在了解循环依赖的时候,我们反复提到了populateBean这个函数,也了解了这个函数的主要功能就是属性填充,那么究竟是如何实现的呢
package org.springframework.beans.factory.support;
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
implements AutowireCapableBeanFactory {
/**
* Populate the bean instance in the given BeanWrapper with the property values
* from the bean definition.
* @param beanName the name of the bean
* @param mbd the bean definition for the bean
* @param bw BeanWrapper with bean instance
* 使用属性值填充给定BeanWrapper中的bean实例
* 来自bean定义。
* @param beanName bean的名称
* @param mbd bean的bean定义
* @param bw BeanWrapper与bean实例
*/
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
if (bw == null) {
if (mbd.hasPropertyValues()) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
}
else {
// Skip property population phase for null instance.
//没有可填充的属性
return;
}
}
// Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
// state of the bean before properties are set. This can be used, for example,
// to support styles of field injection.
//给InstantiationAwareBeanPostProcessors最后一次机会在属性设置前改变bean,可以用来支持属性注入的类型
boolean continueWithPropertyPopulation = true;
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
//返回值是否为继续填充bean
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
continueWithPropertyPopulation = false;
break;
}
}
}
}
//如果后处理器发出停止命令则终止后续执行
if (!continueWithPropertyPopulation) {
return;
}
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||
mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
// Add property values based on autowire by name if applicable.
//根据名称自动注入
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
// Add property values based on autowire by type if applicable.
//根据类型自动注入
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}
//后处理器已经初始化
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
//需要依赖检查
boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE);
if (hasInstAwareBpps || needsDepCheck) {
if (pvs == null) {
pvs = mbd.getPropertyValues();
}
PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
if (hasInstAwareBpps) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
//对所有需要依赖检查的属性进行处理
pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvs == null) {
return;
}
}
}
}
if (needsDepCheck) {
//依赖检查,对应depends-on属性 3.0已弃用
checkDependencies(beanName, mbd, filteredPds, pvs);
}
}
if (pvs != null) {
//将属性应用到bean中
applyPropertyValues(beanName, mbd, bw, pvs);
}
}
在populateBean函数中提供了这样的处理流程
1.InstantiationAwareBeanPostProcessor处理器的postProcessAfterInstantiation函数的应用,可以控制程序是否继续进行属性填充
2.根据注入类型(byName/byType),提取依赖的bean,并统一存入PropertyValues中
3.应用InstantiationAwareBeanPostProcessor处理器的postProcessPropertyValues方法,对所有需要检查的属性进行处理,典型是RequiredAnnotationBeanPostProcessor类中对属性的验证
4.将所有PropertyValues中的属性填充至BeanWrapper中
依赖注入(autowireByName/autowireByType)
autowireByName(beanName, mbd, bw, newPvs);
上文中提到根据注入类型(byName/byType),提取依赖的bean,并统一存入PropertyValues中,首先看下byName是如何实现的
2.4.2.4.5.1根据名称属性填充 autowireByName
/**
* Fill in any missing property values with references to
* other beans in this factory if autowire is set to "byName".
* @param beanName the name of the bean we're wiring up.
* Useful for debugging messages; not used functionally.
* @param mbd bean definition to update through autowiring
* @param bw BeanWrapper from which we can obtain information about the bean
* @param pvs the PropertyValues to register wired objects with
* 使用以下内容填写所有缺少的属性值
* 如果autowire设置为“ byName”,则此工厂中的其他bean。
* @param beanName我们要连接的bean的名称。
* 对于调试消息很有用; 未在功能上使用。
* @param mbd bean定义可通过自动装配进行更新
* @param bw BeanWrapper,我们可以从中获取有关bean的信息
* @param pvs PropertyValues以注册有线对象
*/
protected void autowireByName(
String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
//寻找bw中需要依赖注入的属性
String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
for (String propertyName : propertyNames) {
if (containsBean(propertyName)) {
//递归初始化相关的bean
Object bean = getBean(propertyName);
pvs.add(propertyName, bean);
//注册依赖
registerDependentBean(propertyName, beanName);
if (logger.isDebugEnabled()) {
logger.debug("Added autowiring by name from bean name '" + beanName +
"' via property '" + propertyName + "' to bean named '" + propertyName + "'");
}
}
else {
if (logger.isTraceEnabled()) {
logger.trace("Not autowiring property '" + propertyName + "' of bean '" + beanName +
"' by name: no matching bean found");
}
}
}
}
找到已经加载的bean,并递归实例化,从而加入到pvs中
2.4.2.4.5.2根据类型属性填充 autowireByType
autowireByType(beanName, mbd, bw, newPvs);
/**
* Abstract method defining "autowire by type" (bean properties by type) behavior.
* <p>This is like PicoContainer default, in which there must be exactly one bean
* of the property type in the bean factory. This makes bean factories simple to
* configure for small namespaces, but doesn't work as well as standard Spring
* behavior for bigger applications.
* @param beanName the name of the bean to autowire by type
* @param mbd the merged bean definition to update through autowiring
* @param bw BeanWrapper from which we can obtain information about the bean
* @param pvs the PropertyValues to register wired objects with
* 定义“按类型自动装配”(按类型的Bean属性)行为的抽象方法。
* <p>这类似于PicoContainer的默认值,其中必须恰好有一个bean
* bean工厂中属性类型的*。 这使bean工厂变得简单易行
* 为小型名称空间配置,但不如标准Spring正常工作
* 较大应用程序的行为。
* @param beanName按类型自动装配的bean名称
* @param mbd通过自动装配更新合并的bean定义
* @param bw BeanWrapper,我们可以从中获取有关bean的信息
* @param pvs PropertyValues以注册有线对象
*/
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);
// Don't try autowiring by type for type Object: never makes sense,
// even if it technically is a unsatisfied, non-simple property.
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 = !PriorityOrdered.class.isInstance(bw.getWrappedInstance());
DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager);
//解析指定beanName的属性锁匹配得值,并把解析到的属性名称存储在autowiredArgument中,当存在多个封装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.isDebugEnabled()) {
logger.debug("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);
}
}
}
实现根据名称自动匹配的第一步是寻找bw中需要依赖注入的属性,同样对于根据类型自动匹配的实现来讲,第一步也是寻找bw中需要依赖注入的属性,然后遍历这些属性并寻找类型匹配的bean,其中最复杂的就是寻找类型匹配的bean,同时,Spring中提供了对集合类型注入的支持,如使用注解的方式
@Autowiredprivate List<Test> tests;
Spring将会把所有与Test匹配的类型找出来并注入tests属性中,正是由于这一因素所以在autowireByType函数中,新建了局部遍历autowiredBeanNames,用于存储所有依赖的bean,如果只是对非集合类的属性注入来说,此属性并无用处。
对于寻找类型匹配的逻辑实现封装在了resloveDependency函数中
Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter);
@Override
@Nullable
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()) {
//ObjectFactory类注入的特殊处理
return createOptionalDependency(descriptor, requestingBeanName);
}
else if (ObjectFactory.class == descriptor.getDependencyType() ||
ObjectProvider.class == descriptor.getDependencyType()) {
//javaxInjectProviderClass类注入的特殊处理
return new DependencyObjectProvider(descriptor, requestingBeanName);
}
else if (javaxInjectProviderClass == descriptor.getDependencyType()) {
return new Jsr330ProviderFactory().createDependencyProvider(descriptor, requestingBeanName);
}
else {
Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(
descriptor, requestingBeanName);
if (result == null) {
//通用处理逻辑
result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
}
return result;
}
}
2.4.2.4.5.3通用处理 doResolveDependency
result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
@Nullable
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();
//用于支持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());
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;
}
//根据属性类型找到beanFactory中所有类型的匹配bean
//返回值的构成为:key=匹配的beanName,value=beanName对应的实例化后的bean(通过getBean(beanName)返回)
Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
if (matchingBeans.isEmpty()) {
//如果autowire的require属性为true而找到的匹配项为空则只能抛出异常
if (isRequired(descriptor)) {
raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
}
return null;
}
String autowiredBeanName;
Object instanceCandidate;
//找到的匹配bean数量大于1,
if (matchingBeans.size() > 1) {
autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);
if (autowiredBeanName == null) {
if (isRequired(descriptor) || !indicatesMultipleBeans(type)) {
return descriptor.resolveNotUnique(type, 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);
}
}
寻找类型匹配的执行顺序的时候,首先尝试使用解析器进行解析,如果解析器没有成功解析,那么可能是使用默认的解析器没有做处理,或是使用了自定义解析器,但是对于集合等类型来说并不在解析范围内,所以再次对不同类型进行不同情况的处理,虽然对于不同类型处理方式不一致,但是大致的思路还是一致的
/**
* Raise a NoSuchBeanDefinitionException or BeanNotOfRequiredTypeException
* for an unresolvable dependency.
*/
private void raiseNoMatchingBeanFound(
Class<?> type, ResolvableType resolvableType, DependencyDescriptor descriptor) throws BeansException {
checkBeanNotOfRequiredType(type, descriptor);
throw new NoSuchBeanDefinitionException(resolvableType,
"expected at least 1 bean which qualifies as autowire candidate. " +
"Dependency annotations: " + ObjectUtils.nullSafeToString(descriptor.getAnnotations()));
}
/**
* Determine the autowire candidate in the given set of beans.
* <p>Looks for {@code @Primary} and {@code @Priority} (in that order).
* @param candidates a Map of candidate names and candidate instances
* that match the required type, as returned by {@link #findAutowireCandidates}
* @param descriptor the target dependency to match against
* @return the name of the autowire candidate, or {@code null} if none found
* 在给定的bean组中确定自动装配候选。
* <p>查找{@code @Primary}和{@code @Priority}(按此顺序)。
* @param candidates 候选人名称和候选人实例的Map
* 与{@link #findAutowireCandidates}返回的类型相匹配
* @param descriptor 要匹配的目标依赖项
* @返回自动接线候选者的名称,如果找不到,则为{@code null}
*/
@Nullable
protected String determineAutowireCandidate(Map<String, Object> candidates, DependencyDescriptor descriptor) {
Class<?> requiredType = descriptor.getDependencyType();
String primaryCandidate = determinePrimaryCandidate(candidates, requiredType);
if (primaryCandidate != null) {
return primaryCandidate;
}
String priorityCandidate = determineHighestPriorityCandidate(candidates, requiredType);
if (priorityCandidate != null) {
return priorityCandidate;
}
// Fallback
for (Map.Entry<String, Object> entry : candidates.entrySet()) {
String candidateName = entry.getKey();
Object beanInstance = entry.getValue();
if ((beanInstance != null && this.resolvableDependencies.containsValue(beanInstance)) ||
matchesBeanName(candidateName, descriptor.getDependencyName())) {
return candidateName;
}
}
return null;
}
/**
* Determine whether the given candidate name matches the bean name or the aliases
* stored in this bean definition.
* 确定给定的候选名称是否与bean名称或别名匹配
* 存储在此bean定义中。
*/
protected boolean matchesBeanName(String beanName, @Nullable String candidateName) {
return (candidateName != null &&
(candidateName.equals(beanName) || ObjectUtils.containsElement(getAliases(beanName), candidateName)));
}
2.4.2.4.5.4设置值 applyPropertyValues
applyPropertyValues(beanName, mbd, bw, pvs);
/**
* Apply the given property values, resolving any runtime references
* to other beans in this bean factory. Must use deep copy, so we
* don't permanently modify this property.
* @param beanName the bean name passed for better exception information
* @param mbd the merged bean definition
* @param bw the BeanWrapper wrapping the target object
* @param pvs the new property values
* 应用给定的属性值,解析所有运行时引用
* 该豆工厂中的其他豆。 必须使用深层复制,因此我们
* 不要永久修改此属性。
* @param beanName为更好的异常信息而传递的bean名称
* @param mbd合并的bean定义
* @param bw包裹目标对象的BeanWrapper
* @param pvs新属性值
*/
protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
if (pvs.isEmpty()) {
return;
}
if (System.getSecurityManager() != null && bw instanceof BeanWrapperImpl) {
((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext());
}
MutablePropertyValues mpvs = null;
List<PropertyValue> original;
if (pvs instanceof MutablePropertyValues) {
mpvs = (MutablePropertyValues) pvs;
//如果mpvs中的值已经被转换为对应的类型那么可以直接设置到beanwapper中
if (mpvs.isConverted()) {
// Shortcut: use the pre-converted values as-is.
try {
bw.setPropertyValues(mpvs);
return;
}
catch (BeansException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Error setting property values", ex);
}
}
original = mpvs.getPropertyValueList();
}
else {
//如果pvs并不是使用MutablePropertyValues封装的类型,那么使用原始的属性值获取方法
original = Arrays.asList(pvs.getPropertyValues());
}
TypeConverter converter = getCustomTypeConverter();
if (converter == null) {
converter = bw;
}
//获取对应的解析器
BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter);
// Create a deep copy, resolving any references for values.
List<PropertyValue> deepCopy = new ArrayList<>(original.size());
boolean resolveNecessary = false;
//遍历属性,将属性值转换为对应类的对应属性的类型
for (PropertyValue pv : original) {
if (pv.isConverted()) {
deepCopy.add(pv);
}
else {
String propertyName = pv.getName();
Object originalValue = pv.getValue();
Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);
Object convertedValue = resolvedValue;
boolean convertible = bw.isWritableProperty(propertyName) &&
!PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName);
if (convertible) {
convertedValue = convertForProperty(resolvedValue, propertyName, bw, converter);
}
// Possibly store converted value in merged bean definition,
// in order to avoid re-conversion for every created bean instance.
if (resolvedValue == originalValue) {
if (convertible) {
pv.setConvertedValue(convertedValue);
}
deepCopy.add(pv);
}
else if (convertible && originalValue instanceof TypedStringValue &&
!((TypedStringValue) originalValue).isDynamic() &&
!(convertedValue instanceof Collection || ObjectUtils.isArray(convertedValue))) {
pv.setConvertedValue(convertedValue);
deepCopy.add(pv);
}
else {
resolveNecessary = true;
deepCopy.add(new PropertyValue(pv, convertedValue));
}
}
}
if (mpvs != null && !resolveNecessary) {
mpvs.setConverted();
}
// Set our (possibly massaged) deep copy.
try {
bw.setPropertyValues(new MutablePropertyValues(deepCopy));
}
catch (BeansException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Error setting property values", ex);
}
}
2.4.2.4.6初始化bean initializeBean
exposedObject = initializeBean(beanName, exposedObject, mbd);
在配置bean时有一个init-method的属性,这个属性的作用是在bean实例化之前调用init-method指定的方法,根据用户业务进行实例化,我们现在进入这个方法了,首先看一下方法的执行位置,Spring中程序已经执行过bean的实例化,并且进行了属性的填充,而就在这时会调用用户设置的初始化方法
/**
* Initialize the given bean instance, applying factory callbacks
* as well as init methods and bean post processors.
* <p>Called from {@link #createBean} for traditionally defined beans,
* and from {@link #initializeBean} for existing bean instances.
* @param beanName the bean name in the factory (for debugging purposes)
* @param bean the new bean instance we may need to initialize
* @param mbd the bean definition that the bean was created with
* (can also be {@code null}, if given an existing bean instance)
* @return the initialized bean instance (potentially wrapped)
* @see BeanNameAware
* @see BeanClassLoaderAware
* @see BeanFactoryAware
* @see #applyBeanPostProcessorsBeforeInitialization
* @see #invokeInitMethods
* @see #
* 初始化给定的bean实例,应用工厂回调
* 以及初始化方法和bean后处理器。
* <p>从{@link #createBean}调用,用于传统定义的Bean,
*,并从{@link #initializeBean}获取现有的Bean实例。
* @param beanName工厂中的bean名称(用于调试)
* @param bean我们可能需要初始化的新bean实例
* @param mbd创建该bean的bean定义
*(如果给定现有的bean实例,也可以是{@code null})
* @返回初始化的bean实例(可能包装)
* @请参阅BeanNameAware
* @请参阅BeanClassLoaderAware
* @请参阅BeanFactoryAware
* @请参阅#applyBeanPostProcessorsBeforeInitialization
* @see #invokeInitMethods
* @see #applyBeanPostProcessorsAfterInitialization
*/
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {
//对特殊bean的处理,Aware/BeanClassLoadAware/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;
}
次函数的主要工作是进行客户设定的初始化方法的调用,但是除此之外还有其他工作
2.4.2.4.6.1激活Aware方法
Spring提供一写Aware相关接口,比如BeanFactoryAware/ApplocationContextAware/ResourceLoaderAware/ServletContextAware等,实现这些Aware接口的bean在被初始化之后,可以获取一些相应的资源,例如实现BeanFactoryAware的bean在初始后,Spring容器将会注入BeanFactory的实例,而实现ApplicationContextAware的bean,在被初始化后,将会被注入ApplicationContext的实例等。
2.4.2.4.6.2处理器的应用 applyBeanPostProcessorsBeforeInitialization
BeanPostProcessor给用户充足的权限去更改或者扩展Spring
@Override
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
Object current = beanProcessor.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 beanProcessor : getBeanPostProcessors()) {
Object current = beanProcessor.postProcessAfterInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
2.4.2.4.6.3激活自定义的init方法 invokeInitMethods
invokeInitMethods(beanName, wrappedBean, mbd);
/**
* Give a bean a chance to react now all its properties are set,
* and a chance to know about its owning bean factory (this object).
* This means checking whether the bean implements InitializingBean or defines
* a custom init method, and invoking the necessary callback(s) if it does.
* @param beanName the bean name in the factory (for debugging purposes)
* @param bean the new bean instance we may need to initialize
* @param mbd the merged bean definition that the bean was created with
* (can also be {@code null}, if given an existing bean instance)
* @throws Throwable if thrown by init methods or by the invocation process
* @see #invokeCustomInitMethod
*/
protected void invokeInitMethods(String beanName, final Object bean, @Nullable RootBeanDefinition mbd)
throws Throwable {
//检查是否是isInitializingBean,是的话需要调用afterPropertiesSet方法
boolean isInitializingBean = (bean instanceof InitializingBean);
if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
if (logger.isDebugEnabled()) {
logger.debug("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
}
if (System.getSecurityManager() != null) {
try {
AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
((InitializingBean) bean).afterPropertiesSet();
return null;
}, getAccessControlContext());
}
catch (PrivilegedActionException pae) {
throw pae.getException();
}
}
else {
//属性初始化后的处理
((InitializingBean) bean).afterPropertiesSet();
}
}
if (mbd != null && bean.getClass() != NullBean.class) {
String initMethodName = mbd.getInitMethodName();
if (StringUtils.hasLength(initMethodName) &&
!(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
!mbd.isExternallyManagedInitMethod(initMethodName)) {
//调用自定义初始化方法
invokeCustomInitMethod(beanName, bean, mbd);
}
}
}
2.4.2.4.6.4.注册DisposableBean registerDisposableBeanIfNecessary
registerDisposableBeanIfNecessary
/**
* Add the given bean to the list of disposable beans in this factory,
* registering its DisposableBean interface and/or the given destroy method
* to be called on factory shutdown (if applicable). Only applies to singletons.
* @param beanName the name of the bean
* @param bean the bean instance
* @param mbd the bean definition for the bean
* @see RootBeanDefinition#isSingleton
* @see RootBeanDefinition#getDependsOn
* @see #registerDisposableBean
* @see #registerDependentBean
*/
protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) {
AccessControlContext acc = (System.getSecurityManager() != null ? getAccessControlContext() : null);
if (!mbd.isPrototype() && requiresDestruction(bean, mbd)) {
if (mbd.isSingleton()) {
// Register a DisposableBean implementation that performs all destruction
// work for the given bean: DestructionAwareBeanPostProcessors,
// DisposableBean interface, custom destroy method.
//单例模式下注册需要销毁的bean,此方法中会处理实现DisposableBean的bean,并对所有的bean使用DestructionAwareBeanPostProcessors处理
//DisposableBean DestructionAwareBeanPostProcessor
registerDisposableBean(beanName,
new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
}
else {
// A bean with a custom scope...
Scope scope = this.scopes.get(mbd.getScope());
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope name '" + mbd.getScope() + "'");
}
scope.registerDestructionCallback(beanName,
new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
}
}
}
2.4.2.5实例化后的后处理应用 applyBeanPostProcessorsAfterInitialization
在讲解从缓存中获取单例bean的时候提到过,Spring中的规则是在bean的初始化后尽可能保证将注册的后处理器的postProcessAfterInstantiation方法应用到该bean中,因为如果返回的bean不为空,那么将不会再次经历普通bean的创建过程,所以只能在这里应用后处理器的postProcessAfterInstantiation方法
@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
Object current = beanProcessor.postProcessAfterInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
2.4.3单例创建后的操作 afterSingletonCreation
/** Names of beans that are currently in creation 正在创建的bean名称*/
private final Set<String> singletonsCurrentlyInCreation =
Collections.newSetFromMap(new ConcurrentHashMap<>(16));
/** Names of beans currently excluded from in creation checks 排除校验的bean名称 */
private final Set<String> inCreationCheckExclusions =
Collections.newSetFromMap(new ConcurrentHashMap<>(16));
/**
* Callback after singleton creation.
* <p>The default implementation marks the singleton as not in creation anymore.
* @param beanName the name of the singleton that has been created
* @see #isSingletonCurrentlyInCreation
*/
protected void afterSingletonCreation(String beanName) {
//创建后的bean移出缓存
if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.remove(beanName)) {
throw new IllegalStateException("Singleton '" + beanName + "' isn't currently in creation");
}
}
2.4.4缓存结果并清除加载bean过程中各种辅助状态 addSingleton
//用于保存BeanName和创建bean实例之间的关系,beanName -> bean instance
private final Map<String, Object> singletonObjects = new ConcurrentHashMap(256);
//用于保存BeanName和创建bean的工厂之间的关系,beanName -> ObjectFactory
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap(16);
//保存beanName和创建bean实例之间的关系,与singletonObjects不同的地方在于,当一个单例bean被放到这里面后,bean在创建过程中,可以通过getBean方法获取到,目的是用来检测循环引用
private final Map<String, Object> earlySingletonObjects = new HashMap(16);
//保存当前所有已注册的bean
private final Set<String> registeredSingletons = new LinkedHashSet(256);
/**
* Add the given singleton object to the singleton cache of this factory.
* <p>To be called for eager registration of singletons.
* @param beanName the name of the bean
* @param singletonObject the singleton object
* 将给定的单例对象添加到该工厂的单例缓存中。
* <p>被要求进行单例的急切注册。
* @param beanName bean的名称
* @param singletonObject单例对象
*/
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);
}
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。