本文是针对 Srping 的 BeanFactory.getBean 来进行源码解析, 如果您是第一次看请先看一下 XMLBeanFactory 解析:https://blog.csdn.net/qq_3025… 可以更好的理解 Spring 的注册原理,本篇博客是跟源码一步步看 spring 怎么实现 getBean 源码,Spring 版本为 5.X, 源码已经在每一行上加了注释,方便读者学习。**
GItHub:https://github.com/lantaoGitH…
- 废话不多说,我们直接看源码:
package org.springframework.lantao;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
public class XmlBeanFactoryTest {public static void main(String[] args) {ClassPathResource classPathResource = new ClassPathResource("spring-bean.xml");
BeanFactory beanFactory = new XmlBeanFactory(classPathResource);
UserBean userBean = (UserBean) beanFactory.getBean("userBean");
System.out.println(userBean.getName());
}
}
XMLBeanFactory 解析就不多说了,如果没看过的可以去看我上一篇文章,这里直接看 BeanFactory.getBean()
/**
* 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
*/
@SuppressWarnings("unchecked")
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
// 获取实例名字
final String beanName = transformedBeanName(name);
Object bean;
// Eagerly check singleton cache for manually registered singletons.
// 检查单例缓存中是否存在实例
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 + "'");
}
}
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
} else {
// Fail if we're already creating this bean instance:
// We're assumably within a circular reference.
// 原型 循环引用 抛异常
if (isPrototypeCurrentlyInCreation(beanName)) {throw new BeanCurrentlyInCreationException(beanName);
}
// Check if bean definition exists in this factory.
BeanFactory parentBeanFactory = getParentBeanFactory();
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) {
// 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);
}
}
if (!typeCheckOnly) {// 将指定的 bean 标记为已经创建(或即将创建)。这允许 bean 工厂优化其缓存,以便重复创建指定的 bean
markBeanAsCreated(beanName);
}
try {final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);
// Guarantee initialization of beans that the current bean depends on.
String[] dependsOn = mbd.getDependsOn();
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 实例
if (mbd.isSingleton()) {sharedInstance = getSingleton(beanName, () -> {
try {return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
// Explicitly remove instance from singleton cache: It might have been put there
// eagerly by the creation process, to allow for circular reference resolution.
// Also remove any beans that received a temporary reference to the bean.
destroySingleton(beanName);
throw ex;
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
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);
}
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}else {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, () -> {beforePrototypeCreation(beanName);
try {return createBean(beanName, mbd, args);
}finally {afterPrototypeCreation(beanName);
}
});
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.
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.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;
}
doGetBean 的源码比较长,那它都做了哪些事情呢:
1:转换对应的 beanname,可能有很多人不理解,传入进来的不就应该是 beanName 嘛,其实传入的可能是 BeanFactory,也可能是别名,如果是 BeanFactory, 就要去除它的修饰符,比如传入进来的 &aa,就要转换成 aa,但如果传入进来的是别名,就要取 alias 对应的最终的 beanName,例如别名 A 指向了 B 的 bean 则返回 B 的 beanName,如果别名 A 指向了别名 B,别名 B 指向了 C, 则要返回 C 的 BeanName;
2:检查单例中是否存在实例,会先从缓存中获取,下面会详细讲解;
3:判断原型实例是否存在循环依赖,比如 A 中有 B,B 中有 A,这种情况只有单例模式才会尝试去创建,因为单例模式会提早包曝光实例,存在缓存中,原型模式是不允许的,会抛出类正在创建异常;
4:通过父 BeanFactory 获取 bean;
5:将指定的 bean 标记为已经创建(或即将创建)。这允许 bean 工厂优化其缓存
6:获取 RootBeanDefinition,在 XmlBeanFactory 解析的时候会将 bean 注册到 beanDefinitionMap 中,这里就是在 beanDefinitionMap 中 get,如果不存在则会抛出 bean not found 异常,同时会将 GenericBeanDefinition 转换成 RootBeanDefinition,因为存入时时 GenericBeanDefinition;
7:检查 BeanDefinition 是否是 abstract,如果是则抛出,bean is Aastract 异常;
8:检查依赖,保证该 bean 所以依赖的 bean 都已经初始化,首先这里要了解 depends-on 用来表示一个 bean A 的实例化依靠另一个 bean B 的实例化,但是 A 并不需要持有一个 B 的对象,如果需要的话就不用 depends-on;不理解可以看这篇文章
9:判断 bean 的类型,是 single 还是 proptotype,对应的创建 bean,或者没有指定 scope 的判断,其中出现最多的方法就是 getObjectForBeanInstance,后续会一点点的解析它的源码;
- 接下里我们先看单例缓存获取:
/**
* 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
*/
@Nullable
protected Object getSingleton(String beanName, boolean allowEarlyReference) {Object singletonObject = this.singletonObjects.get(beanName);
// 检查缓存中是否存在实例 isSingletonCurrentlyInCreation 该实例是否在创建中
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
// 如果缓存中实例为 null 则锁定全局变量 singletonObjects 并进行处理
synchronized (this.singletonObjects) {// 尝试从 earlySingletonObjects (创建中提早曝光的 beanFactory) 获取 bean
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
// 尝试从 singletonFactories 获取 beanFactory
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
// 返回获取到的 bean
singletonObject = singletonFactory.getObject();
// 增加缓存
this.earlySingletonObjects.put(beanName, singletonObject);
// 删除缓存
this.singletonFactories.remove(beanName);
}
}
}
}
return singletonObject;
}
首先单例是只允许创建一次,并且单例支持解决循环依赖,第一步会从 singletonObjectsMap 中获取单例,如果发现不存在的话,再通过singletonsCurrentlyInCreation 判断下当前 bean 是否在创建,如果是则从提前曝光的 Map earlySingletonObjects中获取,如果依旧不能存在则在 singletonFactories 中获取 BeanFactory,通过 getBean 进行返回,反之结束了,缓存没有,只能去重新创建了;
- 接下来看 isPrototypeCurrentlyInCreation
/**
* Return whether the specified prototype bean is currently in creation
* (within the current thread).
* @param beanName the name of the bean
*/
protected boolean isPrototypeCurrentlyInCreation(String beanName) {Object curVal = this.prototypesCurrentlyInCreation.get();
return (curVal != null &&
(curVal.equals(beanName) || (curVal instanceof Set && ((Set<?>) curVal).contains(beanName))));
}
在这里判断了原型实例是否存在循环依赖,比如 A 中有 B,B 中有 A,这种情况只有单例模式才会尝试去创建,因为单例模式会提早包曝光实例,存在缓存中,原型模式是不允许的,会抛出类正在创建异常
- markBeanAsCreated 方法源码:
if (!typeCheckOnly) {// 将指定的 bean 标记为已经创建(或即将创建)。这允许 bean 工厂优化其缓存
markBeanAsCreated(beanName);
}
protected void markBeanAsCreated(String beanName) {if (!this.alreadyCreated.contains(beanName)) {synchronized (this.mergedBeanDefinitions) {if (!this.alreadyCreated.contains(beanName)) {
// Let the bean definition get re-merged now that we're actually creating
// the bean... just in case some of its metadata changed in the meantime.
clearMergedBeanDefinition(beanName);
this.alreadyCreated.add(beanName);
}
}
}
}
在上述源码中我们可以看到,这段代码的含义就是讲指定的 bean 标记为已经在创建或者即将创建;在 clearMergedBeanDefinition 方法中可以看到,如果没有标记 bean 正在创建则会删除 BeanDefinnition,接下来会重新创建;
- 继续看 getMergedLocalBeanDefinition 源码:
/**
* Return a merged RootBeanDefinition, traversing the parent bean definition
* if the specified bean corresponds to a child bean definition.
* @param beanName the name of the bean to retrieve the merged definition for
* @return a (potentially merged) RootBeanDefinition for the given bean
* @throws NoSuchBeanDefinitionException if there is no bean with the given name
* @throws BeanDefinitionStoreException in case of an invalid bean definition
*/
protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName) throws BeansException {
// Quick check on the concurrent map first, with minimal locking.
RootBeanDefinition mbd = this.mergedBeanDefinitions.get(beanName);
if (mbd != null) {return mbd;}
return getMergedBeanDefinition(beanName, getBeanDefinition(beanName));
}
在 getBeanDefinition 方法中,spring 是直接从 DefaultListAbleBeanFactory 中的 beanDefinitionMap 获取注册时的 BeanDefinition;
/**
* Return a RootBeanDefinition for the given bean, by merging with the
* parent if the given bean's definition is a child bean definition.
* @param beanName the name of the bean definition
* @param bd the original bean definition (Root/ChildBeanDefinition)
* @param containingBd the containing bean definition in case of inner bean,
* or {@code null} in case of a top-level bean
* @return a (potentially merged) RootBeanDefinition for the given bean
* @throws BeanDefinitionStoreException in case of an invalid bean definition
*/
protected RootBeanDefinition getMergedBeanDefinition(String beanName, BeanDefinition bd, @Nullable BeanDefinition containingBd)
throws BeanDefinitionStoreException {synchronized (this.mergedBeanDefinitions) {
RootBeanDefinition mbd = null;
// Check with full lock now in order to enforce the same merged instance.
if (containingBd == null) {mbd = this.mergedBeanDefinitions.get(beanName);
}
if (mbd == null) {if (bd.getParentName() == null) {
// Use copy of given root bean definition.
if (bd instanceof RootBeanDefinition) {mbd = ((RootBeanDefinition) bd).cloneBeanDefinition();}
else {mbd = new RootBeanDefinition(bd);
}
}
else {
// Child bean definition: needs to be merged with parent.
BeanDefinition pbd;
try {String parentBeanName = transformedBeanName(bd.getParentName());
if (!beanName.equals(parentBeanName)) {pbd = getMergedBeanDefinition(parentBeanName);
}
else {BeanFactory parent = getParentBeanFactory();
if (parent instanceof ConfigurableBeanFactory) {pbd = ((ConfigurableBeanFactory) parent).getMergedBeanDefinition(parentBeanName);
}
else {
throw new NoSuchBeanDefinitionException(parentBeanName,
"Parent name'" + parentBeanName + "'is equal to bean name'" + beanName +
"': cannot be resolved without an AbstractBeanFactory parent");
}
}
}
catch (NoSuchBeanDefinitionException ex) {throw new BeanDefinitionStoreException(bd.getResourceDescription(), beanName,
"Could not resolve parent bean definition'" + bd.getParentName() + "'", ex);
}
// Deep copy with overridden values.
mbd = new RootBeanDefinition(pbd);
mbd.overrideFrom(bd);
}
// Set default singleton scope, if not configured before.
if (!StringUtils.hasLength(mbd.getScope())) {mbd.setScope(RootBeanDefinition.SCOPE_SINGLETON);
}
// A bean contained in a non-singleton bean cannot be a singleton itself.
// Let's correct this on the fly here, since this might be the result of
// parent-child merging for the outer bean, in which case the original inner bean
// definition will not have inherited the merged outer bean's singleton status.
if (containingBd != null && !containingBd.isSingleton() && mbd.isSingleton()) {mbd.setScope(containingBd.getScope());
}
// Cache the merged bean definition for the time being
// (it might still get re-merged later on in order to pick up metadata changes)
if (containingBd == null && isCacheBeanMetadata()) {this.mergedBeanDefinitions.put(beanName, mbd);
}
}
return mbd;
}
}
在 getMergedBeanDefinition 方法中做了几件事情:
1:首先从缓存中 mergedBeanDefinitions 获取 BeanDefinition
2:通过有参构造方法初始化 RootBeanDefinition,这里的实例化涉及到一些参数的 Set 操作,具体代码就不展示了,在 AbstractBeanDefinition 的有参构造方法中;
3:指定 bean 的 scope;
4:把 RootBeanDefinition 加入缓存 mergedBeanDefinitions 中;
在这里只是实例化就不多说了具体的 DeBug 一下就明白了,很简单;
- 我们继续看 checkMergedBeanDefinition 方法:
/**
* Check the given merged bean definition,
* potentially throwing validation exceptions.
* @param mbd the merged bean definition to check
* @param beanName the name of the bean
* @param args the arguments for bean creation, if any
* @throws BeanDefinitionStoreException in case of validation failure
*/
protected void checkMergedBeanDefinition(RootBeanDefinition mbd, String beanName, @Nullable Object[] args)
throws BeanDefinitionStoreException {if (mbd.isAbstract()) {throw new BeanIsAbstractException(beanName);
}
}
checkMergedBeanDefinition 方法是判断 BeanDefinition 是否是 Abstract,如果是则抛出 beanIsAbstractException,这里就不过多解释了, 学过 java 的都懂;
- 接下来就要看当前 Bean 的依赖,需要先实例化依赖:
// Guarantee initialization of beans that the current bean depends on.
// 保证当前 bean 所依赖的 bean 的初始化。String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {for (String dep : dependsOn) {if (isDependent(beanName, dep)) {throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between'" + beanName + "'and'" + dep + "'");
}
registerDependentBean(dep, beanName);
try {getBean(dep);
}
catch (NoSuchBeanDefinitionException ex) {throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"'"+ beanName +"' depends on missing bean '"+ dep +"'", ex);
}
}
}
在这个方法中,如果当前 Bean 是有依赖的话就会先去 GetBean 他的依赖,保证当前 bean 的所有依赖都是初始化过可用的,getBean 大家都不陌生吧,就是 BeanFactory 的 getBean;
- 下面我们看 bean 的创建流程 singleton:
// Create bean instance.
// 创建 bean 实例
if (mbd.isSingleton()) {sharedInstance = getSingleton(beanName, () -> {
try {return createBean(beanName, mbd, args);
}
catch (BeansException ex) {destroySingleton(beanName);
throw ex;
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
上述代码就是创建 Bean 的一个主方法,首先是调用了 getSingleton,接着又用 lambda 执行了 createBean 方法,紧着这又调用了 getObjectForBeanInstance 方法;
- 先来看 createBean 再看 getSingleton 方法:
/**
* 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.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 一个返回代理而不是目标 bean 实例的机会
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {return bean;}
}
catch (Throwable ex) {throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
"BeanPostProcessor before instantiation of bean failed", ex);
}
try {
// 实例化 创建
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isTraceEnabled()) {logger.trace("Finished creating instance of bean'" + beanName + "'");
}
return beanInstance;
}
catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
// A previously detected exception with proper bean creation context already,
// or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
throw ex;
}
catch (Throwable ex) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
}
}
上述代码做了什么:
1:解析 class,如果 BeanDefinition 中存在 beanClass,则直接返回,反之需要通过 ClassLoader 加载,代码就不发了,可自行看源码;
2:方法注入,就是 lookup-method 的注入注入方式,这里就不多赘述了,可看上一遍文章;
3:spring 的原文解释是给 BeanPostProcessors 一个返回代理而不是目标 bean 实例的机会,这里涉及 Aop 的代理,后续文章会详细解释;
4:调用 doCreateBean 进行创建,我们直接看 doCreateBean 方法:
- doCreateBean 方法:
/**
* 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
*/
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
// Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
// 使用对应的策略创建实例 比如工厂
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
final Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {mbd.resolvedTargetType = beanType;}
// Allow post-processors to modify the merged bean definition.
synchronized (mbd.postProcessingLock) {if (!mbd.postProcessed) {
try {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 正在创建中 singletonsCurrentlyInCreation 在 DefaultSingletonBeanRegistry 225 行创建,在创建 bean 之前记录 正在创建 bean
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {if (logger.isTraceEnabled()) {
logger.trace("Eagerly caching bean'" + beanName +
"'to allow for resolving potential circular references");
}
// 在 bean 未实例化之前加入到缓存中,单例支持循环依赖
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
// Initialize the bean instance.
Object exposedObject = bean;
try {
// 对 bean 进行补充,属性注入,bean 依赖
populateBean(beanName, mbd, instanceWrapper);
// 调用初始化方法
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) {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);
}
}
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 {registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
}
上述代码中描述了创建 bean 的流程但是真正的 createBean 还不是在这个方法,在 createBeanInstance 中,我们先看看 CreateBeann 方法都做了什么:
1:使用对应的策略创建实例 createBeanInstance 方法;
2:判断是否提前暴露,条件是(单例 & 允许循环依赖 & 当前 bean 正在创建中 singletonsCurrentlyInCreation 在 DefaultSingletonBeanRegistry 225 行创建,在创建 bean 之前记录 正在创建 bean),如果需要则调用 addSingletonFactory 方法在 bean 未实例化之前加入到缓存中,单例支持循环依赖;
3:对 bean 进行补充,属性注入,bean 依赖;对 ByName,ByType 依赖进行初始化并注册依赖 Bean;
4:调用初始化方法;
5:对依赖处理;
- 看一下 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
*/
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);
// 确保 class 不为空,并且访问权限为 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());
}
// 配置的一种特殊的 callback 回调方法,通过这个 callback 创建 bean
Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
if (instanceSupplier != null) {return obtainFromSupplier(instanceSupplier, beanName);
}
// 如果工厂方式不为空,则使用功能工厂方式进行解析
if (mbd.getFactoryMethodName() != null) {return instantiateUsingFactoryMethod(beanName, mbd, args);
}
// 一个类可能有多个构造器,所以 Spring 得根据参数个数、类型确定需要调用的构造器
// 在使用构造器创建实例后,Spring 会将解析过后确定下来的构造器或工厂方法保存在缓存中,避免再次创建相同 bean 时再次解析
boolean resolved = false;
boolean autowireNecessary = false;
if (args == null) {synchronized (mbd.constructorArgumentLock) {
// 判断构造器或工厂方法是否为 null
if (mbd.resolvedConstructorOrFactoryMethod != null) {
resolved = true;
// 已经解析过 class 的构造器
autowireNecessary = mbd.constructorArgumentsResolved;
}
}
}
if (resolved) {if (autowireNecessary) {
// 构造函数自动注入
return autowireConstructor(beanName, mbd, null, null);
}
else {
// 使用默认构造器
return instantiateBean(beanName, mbd);
}
}
// 需要根据参数解析、确定构造函数
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {return autowireConstructor(beanName, mbd, ctors, args);
}
// Preferred constructors for default construction?
// 默认构造的首选构造器?ctors = mbd.getPreferredConstructors();
if (ctors != null) {return autowireConstructor(beanName, mbd, ctors, null);
}
// No special handling: simply use no-arg constructor.
// 使用默认构造器
return instantiateBean(beanName, mbd);
}
上述方法:
1:解析 class;
2:如果存在 Supplier 回调,则调用 obtainFromSupplier() 进行初始化,如果不等于 null 就直接返回;
3:如果工厂方式不为空,则使用功能工厂方式进行解析;
4:构造函数自动注入 autowireConstructor
5:默认构造器 instantiateBean
- 我们先看看 Supplier 回调的使用:
// 配置的一种特殊的 callback 回调方法,通过这个 callback 创建 bean
Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
if (instanceSupplier != null) {return obtainFromSupplier(instanceSupplier, beanName);
}
/**
* Obtain a bean instance from the given supplier.
* @param instanceSupplier the configured supplier
* @param beanName the corresponding bean name
* @return a BeanWrapper for the new instance
* @since 5.0
* @see #getObjectForBeanInstance
*/
protected BeanWrapper obtainFromSupplier(Supplier<?> instanceSupplier, String beanName) {
Object instance;
String outerBean = this.currentlyCreatedBean.get();
this.currentlyCreatedBean.set(beanName);
try {instance = instanceSupplier.get();
}
finally {if (outerBean != null) {this.currentlyCreatedBean.set(outerBean);
}
else {this.currentlyCreatedBean.remove();
}
}
if (instance == null) {instance = new NullBean();
}
BeanWrapper bw = new BeanWrapperImpl(instance);
initBeanWrapper(bw);
return bw;
}
/**
* Represents a supplier of results.
*
* <p>There is no requirement that a new or distinct result be returned each
* time the supplier is invoked.
*
* <p>This is a <a href="package-summary.html">functional interface</a>
* whose functional method is {@link #get()}.
*
* @param <T> the type of results supplied by this supplier
*
* @since 1.8
*/
@FunctionalInterface
public interface Supplier<T> {
/**
* Gets a result.
*
* @return a result
*/
T get();}
Supplier 就一个 get 方法,该方法会返回一个 T 类型的对象,有点儿类似工厂方法。这个接口有什么作用?用于指定创建 bean 的回调,如果我们设置了这样的回调,那么其他的构造器或者工厂方法都会没有用。在什么设置该参数呢?Spring 提供了相应的
setter
方法,如下:
public void setInstanceSupplier(@Nullable Supplier<?> instanceSupplier) {this.instanceSupplier = instanceSupplier;}
该方法是 AbsTractBeanDefinition 类中的方法,在初始化 RootBeanDefinition 的时候会调用该方法;在源码的 protected AbstractBeanDefinition(BeanDefinition original) 方法中;
- 下面开始解析工厂模式实例化 Bean,后边还有构造函数和默认构造的实例方法 ….. 累
public BeanWrapper instantiateUsingFactoryMethod(String beanName, RootBeanDefinition mbd, @Nullable Object[] explicitArgs) {
// 实例化 BeanWrapperImpl
BeanWrapperImpl bw = new BeanWrapperImpl();
// 初始化 BeanWrapperImpl
this.beanFactory.initBeanWrapper(bw);
Object factoryBean;
Class<?> factoryClass;
boolean isStatic;
// 获取工厂 Bean 这里使用 FactoryBean 县实例化 FactoryBean
// 工厂名称不为空 如下处理
String factoryBeanName = mbd.getFactoryBeanName();
if (factoryBeanName != null) {if (factoryBeanName.equals(beanName)) {throw new BeanDefinitionStoreException(mbd.getResourceDescription(), beanName,
"factory-bean reference points back to the same bean definition");
}
factoryBean = this.beanFactory.getBean(factoryBeanName);
if (mbd.isSingleton() && this.beanFactory.containsSingleton(beanName)) {throw new ImplicitlyAppearedSingletonException();
}
factoryClass = factoryBean.getClass();
isStatic = false;
}
else {
// 工厂名为空,则其可能是一个静态工厂
// It's a static factory method on the bean class.
// 这里使用 Factory-method factory-metohd 无需调用功能工厂类实例下就可以调用工厂功法 但非 static 不可以 需要调用上边的
if (!mbd.hasBeanClass()) {throw new BeanDefinitionStoreException(mbd.getResourceDescription(), beanName,
"bean definition declares neither a bean class nor a factory-bean reference");
}
factoryBean = null;
factoryClass = mbd.getBeanClass();
isStatic = true;
}
// 需要使用的工厂方法
Method factoryMethodToUse = null;
ArgumentsHolder argsHolderToUse = null;
// 要使用的工厂参数
Object[] argsToUse = null;
// 工厂方法的参数
// 如果指定了构造参数则直接使用
// 在调用 getBean 方法的时候指定了方法参数
if (explicitArgs != null) {argsToUse = explicitArgs;}
else {
// 没有指定,则尝试从配置文件中解析
Object[] argsToResolve = null;
synchronized (mbd.constructorArgumentLock) {
// 获取构造函数或工厂方法
factoryMethodToUse = (Method) mbd.resolvedConstructorOrFactoryMethod;
if (factoryMethodToUse != null && mbd.constructorArgumentsResolved) {
// 获取构造参数
argsToUse = mbd.resolvedConstructorArguments;
if (argsToUse == null) {
// 获取构造函数参数的包可见字段
argsToResolve = mbd.preparedConstructorArguments;
}
}
}
if (argsToResolve != null) {
// 缓存中存在, 则解析存储在 BeanDefinition 中的参数
// 如给定方法的构造函数 A(int ,int),则通过此方法后就会把配置文件中的 ("1","1") 转换为 (1,1)
// 缓存中的值可能是原始值也有可能是最终值
argsToUse = resolvePreparedArguments(beanName, mbd, bw, factoryMethodToUse, argsToResolve, true);
}
}
if (factoryMethodToUse == null || argsToUse == null) {
// Need to determine the factory method...
// Try all methods with this name to see if they match the given arguments.
// 需要确定工厂的方法. 尝试所有具有此名称的方法,以查看它们是否与给定的参数匹配。// 获取工厂方法的类全名称
factoryClass = ClassUtils.getUserClass(factoryClass);
// 检索所有方法,这里是对方法进行过滤
Method[] rawCandidates = getCandidateMethods(factoryClass, mbd);
List<Method> candidateList = new ArrayList<>();
for (Method candidate : rawCandidates) {
// 如果有 static 且为工厂方法,则添加到 candidateSet 中
if (Modifier.isStatic(candidate.getModifiers()) == isStatic && mbd.isFactoryMethod(candidate)) {candidateList.add(candidate);
}
}
// 如果静态方法就一个 & getBean 参数 null & 没有构造参数值 直接初始化返回
if (candidateList.size() == 1 && explicitArgs == null && !mbd.hasConstructorArgumentValues()) {Method uniqueCandidate = candidateList.get(0);
if (uniqueCandidate.getParameterCount() == 0) {
mbd.factoryMethodToIntrospect = uniqueCandidate;
synchronized (mbd.constructorArgumentLock) {
mbd.resolvedConstructorOrFactoryMethod = uniqueCandidate;
mbd.constructorArgumentsResolved = true;
mbd.resolvedConstructorArguments = EMPTY_ARGS;
}
bw.setBeanInstance(instantiate(beanName, mbd, factoryBean, uniqueCandidate, EMPTY_ARGS));
return bw;
}
}
Method[] candidates = candidateList.toArray(new Method[0]);
// 排序构造函数
// public 构造函数优先参数数量降序,非 public 构造函数参数数量降序
AutowireUtils.sortFactoryMethods(candidates);
ConstructorArgumentValues resolvedValues = null;
boolean autowiring = (mbd.getResolvedAutowireMode() == AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR);
int minTypeDiffWeight = Integer.MAX_VALUE;
Set<Method> ambiguousFactoryMethods = null;
int minNrOfArgs;
if (explicitArgs != null) {minNrOfArgs = explicitArgs.length;}
else {
// We don't have arguments passed in programmatically, so we need to resolve the
// arguments specified in the constructor arguments held in the bean definition.
// 判断 BeanDefinition 中有没有构造参数值
// getBean() 没有传递参数,则需要解析保存在 BeanDefinition 构造函数中指定的参数
if (mbd.hasConstructorArgumentValues()) {
// 获取构造参数值
ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues();
resolvedValues = new ConstructorArgumentValues();
// 解析构造函数的参数
minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);
}
else {minNrOfArgs = 0;}
}
LinkedList<UnsatisfiedDependencyException> causes = null;
// 循环方法找到 匹配的那个
for (Method candidate : candidates) {
// 获取方法参数
Class<?>[] paramTypes = candidate.getParameterTypes();
if (paramTypes.length >= minNrOfArgs) {
ArgumentsHolder argsHolder;
// getbean 给的参数
if (explicitArgs != null) {
// Explicit arguments given -> arguments length must match exactly.
// 参数不匹配 方法略过
if (paramTypes.length != explicitArgs.length) {continue;}
// 根据参数创建参数持有者
argsHolder = new ArgumentsHolder(explicitArgs);
}
else {
// Resolved constructor arguments: type conversion and/or autowiring necessary.
try {String[] paramNames = null;
// 获取 ParameterNameDiscoverer 对象
// ParameterNameDiscoverer 是用于解析方法和构造函数的参数名称的接口,为参数名称探测器
ParameterNameDiscoverer pnd = this.beanFactory.getParameterNameDiscoverer();
if (pnd != null) {
// 获取指定构造函数的参数名
paramNames = pnd.getParameterNames(candidate);
}
// 在已经解析的构造函数参数值的情况下,创建一个参数持有者对象
argsHolder = createArgumentArray(beanName, mbd, resolvedValues, bw,
paramTypes, paramNames, candidate, autowiring, candidates.length == 1);
}
catch (UnsatisfiedDependencyException ex) {if (logger.isTraceEnabled()) {logger.trace("Ignoring factory method [" + candidate + "] of bean'" + beanName + "':" + ex);
}
// Swallow and try next overloaded factory method.
if (causes == null) {causes = new LinkedList<>();
}
causes.add(ex);
continue;
}
}
// isLenientConstructorResolution 判断解析构造函数的时候是否以宽松模式还是严格模式
// 严格模式:解析构造函数时,必须所有的都需要匹配,否则抛出异常
// 宽松模式:使用具有 "最接近的模式" 进行匹配
// typeDiffWeight:类型差异权重
int typeDiffWeight = (mbd.isLenientConstructorResolution() ?
argsHolder.getTypeDifferenceWeight(paramTypes) : argsHolder.getAssignabilityWeight(paramTypes));
// Choose this factory method if it represents the closest match.
// 代表最接近的类型匹配,则选择作为构造函数
if (typeDiffWeight < minTypeDiffWeight) {
factoryMethodToUse = candidate;
argsHolderToUse = argsHolder;
argsToUse = argsHolder.arguments;
minTypeDiffWeight = typeDiffWeight;
ambiguousFactoryMethods = null;
}
// Find out about ambiguity: In case of the same type difference weight
// for methods with the same number of parameters, collect such candidates
// and eventually raise an ambiguity exception.
// However, only perform that check in non-lenient constructor resolution mode,
// and explicitly ignore overridden methods (with the same parameter signature).
else if (factoryMethodToUse != null && typeDiffWeight == minTypeDiffWeight &&
!mbd.isLenientConstructorResolution() &&
paramTypes.length == factoryMethodToUse.getParameterCount() &&
!Arrays.equals(paramTypes, factoryMethodToUse.getParameterTypes())) {if (ambiguousFactoryMethods == null) {ambiguousFactoryMethods = new LinkedHashSet<>();
ambiguousFactoryMethods.add(factoryMethodToUse);
}
ambiguousFactoryMethods.add(candidate);
}
}
}
// 没有可执行的工厂方法,抛出异常
if (factoryMethodToUse == null) {if (causes != null) {UnsatisfiedDependencyException ex = causes.removeLast();
for (Exception cause : causes) {this.beanFactory.onSuppressedException(cause);
}
throw ex;
}
List<String> argTypes = new ArrayList<>(minNrOfArgs);
if (explicitArgs != null) {for (Object arg : explicitArgs) {argTypes.add(arg != null ? arg.getClass().getSimpleName() : "null");
}
}
else if (resolvedValues != null) {Set<ValueHolder> valueHolders = new LinkedHashSet<>(resolvedValues.getArgumentCount());
valueHolders.addAll(resolvedValues.getIndexedArgumentValues().values());
valueHolders.addAll(resolvedValues.getGenericArgumentValues());
for (ValueHolder value : valueHolders) {String argType = (value.getType() != null ? ClassUtils.getShortName(value.getType()) : (value.getValue() != null ? value.getValue().getClass().getSimpleName() : "null"));
argTypes.add(argType);
}
}
String argDesc = StringUtils.collectionToCommaDelimitedString(argTypes);
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"No matching factory method found:" +
(mbd.getFactoryBeanName() != null ?
"factory bean'" + mbd.getFactoryBeanName() + "';" : "") +"factory method '"+ mbd.getFactoryMethodName() +"("+ argDesc +")'." +
"Check that a method with the specified name" +
(minNrOfArgs > 0 ? "and arguments" : "") +"exists and that it is " +
(isStatic ? "static" : "non-static") + ".");
}
else if (void.class == factoryMethodToUse.getReturnType()) {throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Invalid factory method'" + mbd.getFactoryMethodName() +
"': needs to have a non-void return type!");
}
else if (ambiguousFactoryMethods != null) {throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Ambiguous factory method matches found in bean'" + beanName + "'" +"(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities): " +
ambiguousFactoryMethods);
}
if (explicitArgs == null && argsHolderToUse != null) {
// 指定工厂方法
mbd.factoryMethodToIntrospect = factoryMethodToUse;
// 将解析的构造函数加入缓存
argsHolderToUse.storeCache(mbd, factoryMethodToUse);
}
}
Assert.state(argsToUse != null, "Unresolved factory method arguments");
bw.setBeanInstance(instantiate(beanName, mbd, factoryBean, factoryMethodToUse, argsToUse));
return bw;
}
上述这段代码,怎么说呢,为什么都写一起,为什么不分方法写,每个方法明确干什么,看这个方法需要毅力,读者好好看 ……. 先来看看这个方法都做了啥:
1:首先实例化 BeanWrapperImpl
2:初始化 BeanWrapperImpl
3:获取 FactoryBean Name,看这里之前读者如果不了解 factory-bean 和 factory-mothod 请点击,在这里会判断 factoryBeannName 是否为 null,如果不是则初始化工厂 bean,代码体现在 factoryBean = this.beanFactory.getBean(factoryBeanName)这里,否则一定是一个 static 修饰的工厂方法,直接调用即可;
4:缓存中获取构造或工厂方法,构造参数,在线解释一下:;
- constructorArgumentLock:构造缓存使用的锁;
- resolvedConstructorOrFactoryMethod:构造函数或工厂方法;
- resolvedConstructorArguments:构造参数
如果缓存中存在,则需要调用
resolvePreparedArguments()
方法进行转换,因为缓存中的值有可能是最终值也有可能不是最终值,比如我们构造函数中的类型为 Integer 类型的 1,但是原始的参数类型有可能是 String 类型的 1,所以即便是从缓存中得到了构造参数也需要经过一番的类型转换确保参数类型完全对应。5:如果缓存中或上送的参数没有则需要解析了,需要通过反射获取所有方法,如果获取的符合条件的 static 的方法就一个,并且还没有构造方法参数,则直接初始化返回;代码如下:
// 如果静态方法就一个 & getBean 参数 null & 没有构造参数值 直接初始化返回
if (candidateList.size() == 1 && explicitArgs == null && !mbd.hasConstructorArgumentValues()) {Method uniqueCandidate = candidateList.get(0);
if (uniqueCandidate.getParameterCount() == 0) {
mbd.factoryMethodToIntrospect = uniqueCandidate;
synchronized (mbd.constructorArgumentLock) {
mbd.resolvedConstructorOrFactoryMethod = uniqueCandidate;
mbd.constructorArgumentsResolved = true;
mbd.resolvedConstructorArguments = EMPTY_ARGS;
}
bw.setBeanInstance(instantiate(beanName, mbd, factoryBean, uniqueCandidate, EMPTY_ARGS));
return bw;
}
}
6: 如果显示提供了参数(explicitArgs != null), 则直接使用,反之需要获取 ConstructorArgumentValues 值,并且解析构造函数,这里比较复杂,建议读者 debug;
7:循环匹配,直到找到匹配的构造函数;如果找不到则抛出异常,无可用函数;代码如下:
// 循环方法找到 匹配的那个
for (Method candidate : candidates) {
// 获取方法参数
Class<?>[] paramTypes = candidate.getParameterTypes();
if (paramTypes.length >= minNrOfArgs) {
ArgumentsHolder argsHolder;
// getbean 给的参数
if (explicitArgs != null) {
// Explicit arguments given -> arguments length must match exactly.
// 参数不匹配 方法略过
if (paramTypes.length != explicitArgs.length) {continue;}
// 根据参数创建参数持有者
argsHolder = new ArgumentsHolder(explicitArgs);
}
else {
// Resolved constructor arguments: type conversion and/or autowiring necessary.
try {String[] paramNames = null;
// 获取 ParameterNameDiscoverer 对象
// ParameterNameDiscoverer 是用于解析方法和构造函数的参数名称的接口,为参数名称探测器
ParameterNameDiscoverer pnd = this.beanFactory.getParameterNameDiscoverer();
if (pnd != null) {
// 获取指定构造函数的参数名
paramNames = pnd.getParameterNames(candidate);
}
// 在已经解析的构造函数参数值的情况下,创建一个参数持有者对象
argsHolder = createArgumentArray(beanName, mbd, resolvedValues, bw,
paramTypes, paramNames, candidate, autowiring, candidates.length == 1);
}
catch (UnsatisfiedDependencyException ex) {if (logger.isTraceEnabled()) {logger.trace("Ignoring factory method [" + candidate + "] of bean'" + beanName + "':" + ex);
}
// Swallow and try next overloaded factory method.
if (causes == null) {causes = new LinkedList<>();
}
causes.add(ex);
continue;
}
}
// isLenientConstructorResolution 判断解析构造函数的时候是否以宽松模式还是严格模式
// 严格模式:解析构造函数时,必须所有的都需要匹配,否则抛出异常
// 宽松模式:使用具有 "最接近的模式" 进行匹配
// typeDiffWeight:类型差异权重
int typeDiffWeight = (mbd.isLenientConstructorResolution() ?
argsHolder.getTypeDifferenceWeight(paramTypes) : argsHolder.getAssignabilityWeight(paramTypes));
// Choose this factory method if it represents the closest match.
// 代表最接近的类型匹配,则选择作为构造函数
if (typeDiffWeight < minTypeDiffWeight) {
factoryMethodToUse = candidate;
argsHolderToUse = argsHolder;
argsToUse = argsHolder.arguments;
minTypeDiffWeight = typeDiffWeight;
ambiguousFactoryMethods = null;
}
// Find out about ambiguity: In case of the same type difference weight
// for methods with the same number of parameters, collect such candidates
// and eventually raise an ambiguity exception.
// However, only perform that check in non-lenient constructor resolution mode,
// and explicitly ignore overridden methods (with the same parameter signature).
else if (factoryMethodToUse != null && typeDiffWeight == minTypeDiffWeight &&
!mbd.isLenientConstructorResolution() &&
paramTypes.length == factoryMethodToUse.getParameterCount() &&
!Arrays.equals(paramTypes, factoryMethodToUse.getParameterTypes())) {if (ambiguousFactoryMethods == null) {ambiguousFactoryMethods = new LinkedHashSet<>();
ambiguousFactoryMethods.add(factoryMethodToUse);
}
ambiguousFactoryMethods.add(candidate);
}
}
}
// 没有可执行的工厂方法,抛出异常
if (factoryMethodToUse == null) {if (causes != null) {UnsatisfiedDependencyException ex = causes.removeLast();
for (Exception cause : causes) {this.beanFactory.onSuppressedException(cause);
}
throw ex;
}
List<String> argTypes = new ArrayList<>(minNrOfArgs);
if (explicitArgs != null) {for (Object arg : explicitArgs) {argTypes.add(arg != null ? arg.getClass().getSimpleName() : "null");
}
}
else if (resolvedValues != null) {Set<ValueHolder> valueHolders = new LinkedHashSet<>(resolvedValues.getArgumentCount());
valueHolders.addAll(resolvedValues.getIndexedArgumentValues().values());
valueHolders.addAll(resolvedValues.getGenericArgumentValues());
for (ValueHolder value : valueHolders) {String argType = (value.getType() != null ? ClassUtils.getShortName(value.getType()) :
(value.getValue() != null ? value.getValue().getClass().getSimpleName() : "null"));
argTypes.add(argType);
}
}
String argDesc = StringUtils.collectionToCommaDelimitedString(argTypes);
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"No matching factory method found:" +
(mbd.getFactoryBeanName() != null ?
"factory bean'" + mbd.getFactoryBeanName() + "';" : "") +"factory method '"+ mbd.getFactoryMethodName() +"("+ argDesc +")'." +
"Check that a method with the specified name" +
(minNrOfArgs > 0 ? "and arguments" : "") +"exists and that it is " +
(isStatic ? "static" : "non-static") + ".");
}
8:指定工厂那个方法,并且将解析的构造函数信息加入缓存中,代码如下:
if (explicitArgs == null && argsHolderToUse != null) {
// 指定工厂方法
mbd.factoryMethodToIntrospect = factoryMethodToUse;
// 将解析的构造函数加入缓存
argsHolderToUse.storeCache(mbd, factoryMethodToUse);
}
public void storeCache(RootBeanDefinition mbd, Executable constructorOrFactoryMethod) {synchronized (mbd.constructorArgumentLock) {
mbd.resolvedConstructorOrFactoryMethod = constructorOrFactoryMethod;
mbd.constructorArgumentsResolved = true;
if (this.resolveNecessary) {mbd.preparedConstructorArguments = this.preparedArguments;}
else {mbd.resolvedConstructorArguments = this.arguments;}
}
}
10:通过反射实例化 Bean,源码:
@Override
public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner,
@Nullable Object factoryBean, final Method factoryMethod, Object... args) {
try {if (System.getSecurityManager() != null) {AccessController.doPrivileged((PrivilegedAction<Object>) () -> {ReflectionUtils.makeAccessible(factoryMethod);
return null;
});
}
else {ReflectionUtils.makeAccessible(factoryMethod);
}
Method priorInvokedFactoryMethod = currentlyInvokedFactoryMethod.get();
try {currentlyInvokedFactoryMethod.set(factoryMethod);
// 利用反射
Object result = factoryMethod.invoke(factoryBean, args);
if (result == null) {result = new NullBean();
}
return result;
}
finally {if (priorInvokedFactoryMethod != null) {currentlyInvokedFactoryMethod.set(priorInvokedFactoryMethod);
}
else {currentlyInvokedFactoryMethod.remove();
}
}
}
catch (IllegalArgumentException ex) {
throw new BeanInstantiationException(factoryMethod,
"Illegal arguments to factory method'" + factoryMethod.getName() + "';" +
"args:" + StringUtils.arrayToCommaDelimitedString(args), ex);
}
catch (IllegalAccessException ex) {
throw new BeanInstantiationException(factoryMethod,
"Cannot access factory method'" + factoryMethod.getName() + "'; is it public?", ex);
}
catch (InvocationTargetException ex) {String msg = "Factory method'" + factoryMethod.getName() + "'threw exception";
if (bd.getFactoryBeanName() != null && owner instanceof ConfigurableBeanFactory &&
((ConfigurableBeanFactory) owner).isCurrentlyInCreation(bd.getFactoryBeanName())) {msg = "Circular reference involving containing bean'" + bd.getFactoryBeanName() + "'- consider" +
"declaring the factory method as static for independence from its containing instance." + msg;
}
throw new BeanInstantiationException(factoryMethod, msg, ex.getTargetException());
}
}
- 上述工厂模式实例化 Bean 写的不是很详细,尽量 debug 源码去一步步看才能理解,下面看构造器实例化 autowireConstructor
工厂实例化和构造函数实例化这两个大方法都需要读者自己 deBug,这样可更好的理解下面说一下都做了什么:
1:实例化 BeanWrapperImpl
2:初始化 BeanWrapperImpl
3:构造参数如果在 getBean 是传入则使用,反之需要从缓存中获取并解析参数类型:
- constructorArgumentLock:构造缓存使用的锁;
- resolvedConstructorOrFactoryMethod:构造函数或工厂方法;
- resolvedConstructorArguments:构造参数
代码如下:
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, true); }
4:解析构造函数,如果中有上送,则使用,如果没有则从 beanClass 中获取,解析后加入缓存,代码是:
if (constructorToUse == null || argsToUse == null) {// 接受指定的构造函数(如果有的话)。. Constructor<?>[] candidates = chosenCtors; if (candidates == null) { // 从 class 中获取 Class<?> beanClass = mbd.getBeanClass(); try { // 从 class 获取构造器 判断是否是 public 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); } } // 构造参数 value == null 直接返回 if (candidates.length == 1 && explicitArgs == null && !mbd.hasConstructorArgumentValues()) {Constructor<?> uniqueCandidate = candidates[0]; if (uniqueCandidate.getParameterCount() == 0) {synchronized (mbd.constructorArgumentLock) { // 构造器或工厂方法 mbd.resolvedConstructorOrFactoryMethod = uniqueCandidate; // 构造函数参数解析 mbd.constructorArgumentsResolved = true; // 构造函数参数 mbd.resolvedConstructorArguments = EMPTY_ARGS; } bw.setBeanInstance(instantiate(beanName, mbd, uniqueCandidate, EMPTY_ARGS)); return bw; } } // 需要解析构造函数参数 boolean autowiring = (chosenCtors != null || mbd.getResolvedAutowireMode() == AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR); ConstructorArgumentValues resolvedValues = null; int minNrOfArgs; if (explicitArgs != null) {minNrOfArgs = explicitArgs.length;} else {ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues(); resolvedValues = new ConstructorArgumentValues(); // 解析构造函数参数 minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues); } 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 != 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; } ConstructorResolver.ArgumentsHolder argsHolder; if (resolvedValues != null) { try { // 从注解上获取参数名称 String[] paramNames = ConstructorResolver.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, candidates.length == 1); } catch (UnsatisfiedDependencyException ex) {if (logger.isTraceEnabled()) {logger.trace("Ignoring constructor [" + candidate + "] of bean'" + beanName + "':" + ex); } // Swallow and try next constructor. if (causes == null) {causes = new LinkedList<>(); } causes.add(ex); continue; } } else { // 无参构造 // Explicit arguments given -> arguments length must match exactly. if (paramTypes.length != explicitArgs.length) {continue;} argsHolder = new ConstructorResolver.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 != null) { // 加入缓存 argsHolderToUse.storeCache(mbd, constructorToUse); } }
5:实例化 Bean,源码:
@Override public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner, final Constructor<?> ctor, Object... args) { // 如果没使用 lookuo 或 replace 则直接使用反射创建 if (!bd.hasMethodOverrides()) {if (System.getSecurityManager() != null) {// use own privileged to change accessibility (when security is on) AccessController.doPrivileged((PrivilegedAction<Object>) () -> {ReflectionUtils.makeAccessible(ctor); return null; }); } // 直接使用反射方式创建你 return BeanUtils.instantiateClass(ctor, args); } else {return instantiateWithMethodInjection(bd, beanName, owner, ctor, args); } }
- 下面说一下默认构造器 instantiateBean 实例化 Bean:
/**
* 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
*/
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);
}
}
@Override
public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
// Don't override the class with CGLIB if no overrides.
if (!bd.hasMethodOverrides()) {
Constructor<?> constructorToUse;
synchronized (bd.constructorArgumentLock) {
// 获取构造器
constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;
if (constructorToUse == null) {
// 获取 clazz
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);
}
}
}
// 实例化 class
return BeanUtils.instantiateClass(constructorToUse);
}
else {
// Must generate CGLIB subclass.
return instantiateWithMethodInjection(bd, beanName, owner);
}
}
上述代码是使用默认构造器实例化 Bean 的代码,这里我就不多赘述了,使用工厂模式和构造参数实例化 Bean 的代码都看过了,这里就很容易理解了;下面我们接着流程说 getSingleton 方法:
- getSingleton 方法:
/**
* 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
*/
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {Assert.notNull(beanName, "Bean name must not be null");
// 加锁,全局变量需要同步
synchronized (this.singletonObjects) {
// 查看单例 bean 是否创建国如果有直接使用
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {if (this.singletonsCurrentlyInDestruction) {
throw new BeanCreationNotAllowedException(beanName,
"Singleton bean creation not allowed while singletons of this factory are in destruction" +
"(Do not request a bean from a BeanFactory in a destroy method implementation!)");
}
if (logger.isDebugEnabled()) {logger.debug("Creating shared instance of singleton bean'" + beanName + "'");
}
// 记录加载状态 书中 99 页
beforeSingletonCreation(beanName);
boolean newSingleton = false;
boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
if (recordSuppressedExceptions) {this.suppressedExceptions = new LinkedHashSet<>();
}
try {singletonObject = singletonFactory.getObject();
newSingleton = true;
}
catch (IllegalStateException ex) {
// Has the singleton object implicitly appeared in the meantime ->
// if yes, proceed with it since the exception indicates that state.
singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {throw ex;}
}
catch (BeanCreationException ex) {if (recordSuppressedExceptions) {for (Exception suppressedException : this.suppressedExceptions) {ex.addRelatedCause(suppressedException);
}
}
throw ex;
}
finally {if (recordSuppressedExceptions) {this.suppressedExceptions = null;}
// 删除加载状态
afterSingletonCreation(beanName);
}
if (newSingleton) {addSingleton(beanName, singletonObject);
}
}
return singletonObject;
}
}
这里我们直接说这个方法干了什么事情吧,如下:
1:首先是全局锁 singletonObjects;
2:查看缓存中是否存在,如果有则判断获取的 Bean 是否在销毁阶段;
3:使用 singletonsCurrentlyInCreation 记录加载状态;
4:使用 createBean 方法返回的 ObjectFactory 获取 bean,并指定这次创建是一个新的单例;
5:在 singletonsCurrentlyInCreation 中删除加载状态;
6:增加缓存,代码如下:
/** * 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 */ 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); } }
- 接下来就看一看 getBean 调用最多的方法 getObjectForBeanInstance:
/**
* 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
*/
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 是工厂相关的(& 前缀),并且 beanInstance 又不是 FactoryBean 类 则验证不通过
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 可能是 beanfactory,如果是 FactoryBean 我们使用它去创建实例,但是如果用户想要直接获取工厂实例而不是工厂的 getObject 方法所对应的实例,// 那么传入的 name 应该加前缀 &
if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {return beanInstance;}
Object object = null;
if (mbd == null) {
// 尝试从缓存中加载实例
object = getCachedObjectForFactoryBean(beanName);
}
if (object == null) {
// Return bean instance from factory.
// beanInstance 一定是 FactoryBean 了
FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
// Caches object obtained from FactoryBean if it is a singleton.
// 在 beanDefinitionMap 获取 beanDefition ,beanDefinitionMap 是注册时候的 Map
if (mbd == null && containsBeanDefinition(beanName)) {
// 将 xml 解析时存入的 GernericBeanDefinition 转换成 RootBeanDefinition
mbd = getMergedLocalBeanDefinition(beanName);
}
// 是否是用户定义而不是应用程序本身定义
boolean synthetic = (mbd != null && mbd.isSynthetic());
object = getObjectFromFactoryBean(factory, beanName, !synthetic);
}
return object;
}
上述代码有两个判断:
1:如果指定的 name 是工厂相关的(& 前缀),并且 beanInstance 类型不是 FactoryBean 则抛出 BeanIsNotAFactoryBean 异常;
2:如果 beanInstance 不是 FactoryBean 或者 指定的 name 是工厂相关的(& 前缀)则直接返回 beanInstance;
这两个条件可以好好理解下,第一个应该没问题,如果指定的是工厂相关的,并且 beanInstance 类是不是 FactoryBean 则抛出异常,第二个就可以理解 beanInstance 如果不是 FactoryBean 就直接返回,并且第二个条件的 BeanFactoryUtils.isFactoryDereference(name)永远都不会是 true,因为如果这一条件成立,则第一个条件则通不过会直接抛出异常,那么下边的代码就是在处理 beanInstrace 是 BeanFactory,但是传入的 name 不是 &name;
3:下面的代码就很简单了,mbd 这个参数不会为 null,只有在获取缓存的时候会是 null,这里就不做多解释了,直接将 BeanInstance 类型强转成 FactoryBean<T>,然后调用 getObjectFromFactoryBean 方法进行 getObject 返回;
4:FactoryBean 不理解的可以看一下这篇文章,有例子:https://blog.csdn.net/qq_3025…
总结
总结一下,在 getSinngnleton 中不断的使用缓存就是因为是单例的不允许重复创建,说一下重点:
1:如果是单例则先从缓存中获取,没有在调用 getSingleton 方法创建;
2:检查 bean 是否是 abstract
3:保证当前 bean 所依赖的 bean 的初始化,如果没有先初始化依赖;
4:获取 BeanDefinition,BeanDefinition 是在注册的时候实例化然后存入缓存的,这里直接取过来做一下类型转换即可;
5:如果是单例则调用 getSingleton 方法,如果是原型则调用 isPrototype 下面的代码块,如果都不是的话使用默认创建(原型);
6:在 bean 创建前后会使用 singletonsCurrentlyInCreation 或 prototypesCurrentlyInCreation 标记类是否正在创建中,给后续判断使用;
7:bean 实例化的方式,在创建实例之前做了一个判断,如果有则通过 InstanceSupplier.et 方法直接返回,工厂方法实例化(instantiateUsingFactoryMethod),构造器实例化(autowireConstructor),默认构造器实例化(instantiateBean),这里是读者需要看源码的的重点,
8:bean 在创建前会提前暴露实例并增加缓存,保证如果有别人依赖可以直接从缓存你中取,解决循环依赖问题;
9:对 bean 的赋值属性的注入(populateBean 方法);
10:调用初始化方法,initializeBean;
对于 9 和 10 在代码中没有做详细的讲解,但是在源码中做了一些注释,可以自行 debug 看一下很简单,主要是太多了,早知道就分开写了,很累 …. 不知道作为读者的你能否能看下去;
码字不易,转你发请注明出处:https://mp.csdn.net/postedit/…
博客地址:https://lantaogithub.github.io
简书:https://www.jianshu.com/u/bfb…
CSDN:https://blog.csdn.net/qq_3025…
开源中国:https://my.oschina.net/u/3948555
掘金:https://juejin.im/user/5c8c6f…
思否:https://segmentfault.com/u/qi…