转换对应的 beanName 是根据 getBean(String name) 方法传入的 name 参数进行的,传入的 name 并不一定是 beanName,可能是别名,也可能是 FactoryBean 。至于什么是 FactoryBean ,后面会提及。由于 name 的多种可能,Spring会进行对应的转换。
去除 FactoryBean 的修饰符,一般就是去除 name 参数的 & 前缀,从代码上能够清晰的看出;
取指定的 alias 所表示的最终 beanName,例如别名 A 指向别名 B,别名 B 指向名称为 C 的 bean,则最后返回 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));}
1
2
3
4
5
6
7
8
9
1
2
3
4
5
6
7
8
9
去除 FactoryBean 的修饰符:
/** * 去掉xml中bean标签name属性的前缀& * 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 */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;}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
取指定的 alias 所表示的最终 beanName:
/** * Determine the raw name, resolving aliases to canonical names. * @param name the user-specified name * @return the transformed name */public String canonicalName(String name) { String canonicalName = name; // Handle aliasing... String resolvedName; do { resolvedName = this.aliasMap.get(canonicalName); if (resolvedName != null) { canonicalName = resolvedName; } } while (resolvedName != null); return canonicalName;}
Spring能够尝试解决的循环依赖问题只有单例模式下,对于原型模式的循环依赖问题Spring是没有方法解决的。因为在原型模式(prototype)下,如果 A 依赖 B,B 同时又依赖 A,那么就会出现创建 A 时因为创建依赖 B 而又要创建 A ,因为是多例的,所以会一直循环创建。Spring对于原型模式下的循环依赖会进行检测,检测代码为 isPrototypeCurrentlyInCreation(beanName) ,如果为 true,则会抛出异常。
if (isPrototypeCurrentlyInCreation(beanName)) { throw new BeanCurrentlyInCreationException(beanName);}
if (mbd.isSingleton()) { .....}else if (mbd.isPrototype()) { // It's a prototype -> create a new instance. // prototype原型模式的创建(new) .....}else { // 指定的scope上实例化bean .....}
/** * Return whether the specified singleton bean is currently in creation * (within the entire factory). * @param beanName the name of the bean */public boolean isSingletonCurrentlyInCreation(String beanName) { return this.singletonsCurrentlyInCreation.contains(beanName);}
1
2
3
4
5
6
7
8
1
2
3
4
5
6
7
8
代码中涉及到很多个存储 bean 的不同 map 集合。我们来罗列一下:
/** 用于保存BeanName和创建bean实例之间的关系Cache of singleton objects: bean name to bean instance. */private final Map singletonObjects = new ConcurrentHashMap<>(256);/** 用于保存BeanName和创建bean的工厂之间的关系 Cache of singleton factories: bean name to ObjectFactory. */private final Map=""???>> singletonFactories = new HashMap<>(16);/** 也是保存BeanName和创建bean实例之间的关系,与singletonObjects不同之处在于,当一个单例bean被放在里面后, * 那么bean还在创建过程中,就可以通过getBean方法获取到了,其目的是用来循环检测引用 * Cache of early singleton objects: bean name to bean instance. */private final Map earlySingletonObjects = new HashMap<>(16);/** 用来保存当前所有已注册的bean Set of registered singletons, containing the bean names in registration order. */private final Set registeredSingletons = new LinkedHashSet<>(256);
/** * 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 */@Nullableprotected Object getCachedObjectForFactoryBean(String beanName) { return this.factoryBeanObjectCache.get(beanName);}
/** * 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() */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
/** * 缓存中没有需要新创建单例初始状态的bean * 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) { // 单例bean的初始化 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 + "'"); } // 记录加载状态,通过this.singletonsCurrentlyInCreation.add(beanName)将当前正要创建的bean记录在缓存中, // 便于对循环依赖进行检测 beforeSingletonCreation(beanName); // 创建单例bean是否成功的标识 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; } // 创建完bean之后需要移除缓存中对该bean正在加载状态的记录 afterSingletonCreation(beanName); } // 加入缓存并删除加载bean过程中所记录的各种辅助状态 if (newSingleton) { addSingleton(beanName, singletonObject); } } return singletonObject; }}
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);}
protected void afterSingletonCreation(String beanName) { if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.remove(beanName)) { throw new IllegalStateException("Singleton '" + beanName + "' isn't currently in creation"); }}
1
2
3
4
5
1
2
3
4
5
将结果记录至缓存并删除加载 bean 过程中所记录的各种辅助状态;
/** * 添加缓存并移除辅助变量 * Add the given singleton object to the singleton cache of this factory. *
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); }}
在开始我们对于该属性赋值为 String 类型的 class 名称,而这一步骤的工作就是确保该属性类型是 Class 类型,可以由 class 名称进行转换。createBean() 中通过 resolveBeanClass(mbd, beanName) 方法来进行处理:
/** * Resolve the bean class for the specified bean definition, * resolving a bean class name into a Class reference (if necessary) * and storing the resolved Class in the bean definition for further use. * @param mbd the merged bean definition to determine the class for * @param beanName the name of the bean (for error handling purposes) * @param typesToMatch the types to match in case of internal type matching purposes * (also signals that the returned {@code Class} will never be exposed to application code) * @return the resolved bean class (or {@code null} if none) * @throws CannotLoadBeanClassException if we failed to load the class */@Nullableprotected Class resolveBeanClass(final RootBeanDefinition mbd, String beanName, final Class... typesToMatch) throws CannotLoadBeanClassException { try { // mbd中是否含有class信息,而且是Class类型的,有则直接返回 if (mbd.hasBeanClass()) { return mbd.getBeanClass(); } // 没有则需要通过doResolveBeanClass()获取 if (System.getSecurityManager() != null) { return AccessController.doPrivileged((PrivilegedExceptionAction<>???>>) () -> doResolveBeanClass(mbd, typesToMatch), getAccessControlContext()); } else { return doResolveBeanClass(mbd, typesToMatch); } } catch (PrivilegedActionException pae) { ClassNotFoundException ex = (ClassNotFoundException) pae.getException(); throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), ex); } catch (ClassNotFoundException ex) { throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), ex); } catch (LinkageError err) { throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), err); }}???>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
同样,如果 BeanDefinition 中本身就已经存储的是 Class 属性的 beanClass,那么直接返回即可。否则,需要委托 doResolveBeanClass(mbd, typesToMatch) 做 String 类型的 beanClass 转换为 Class 类型。
@Nullableprivate Class doResolveBeanClass(RootBeanDefinition mbd, Class... typesToMatch) throws ClassNotFoundException { ClassLoader beanClassLoader = getBeanClassLoader(); ClassLoader classLoaderToUse = beanClassLoader; if (!ObjectUtils.isEmpty(typesToMatch)) { // When just doing type checks (i.e. not creating an actual instance yet), // use the specified temporary class loader (e.g. in a weaving scenario). ClassLoader tempClassLoader = getTempClassLoader(); if (tempClassLoader != null) { classLoaderToUse = tempClassLoader; if (tempClassLoader instanceof DecoratingClassLoader) { DecoratingClassLoader dcl = (DecoratingClassLoader) tempClassLoader; for (Class typeToMatch : typesToMatch) { dcl.excludeClass(typeToMatch.getName()); } } } } // String类型的beanClass转换 String className = mbd.getBeanClassName(); if (className != null) { Object evaluated = evaluateBeanDefinitionString(className, mbd); if (!className.equals(evaluated)) { // A dynamically resolved expression, supported as of 4.2... if (evaluated instanceof Class) { return (Class) evaluated; } else if (evaluated instanceof String) { return ClassUtils.forName((String) evaluated, classLoaderToUse); } else { throw new IllegalStateException("Invalid class name expression result: " + evaluated); } } // When resolving against a temporary class loader, exit early in order // to avoid storing the resolved Class in the bean definition. if (classLoaderToUse != beanClassLoader) { return ClassUtils.forName(className, classLoaderToUse); } } return mbd.resolveBeanClass(beanClassLoader);}
/** * 验证并准备该bean的method-overrides * 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 */public void prepareMethodOverrides() throws BeanDefinitionValidationException { // Check that lookup methods exists. if (hasMethodOverrides()) { Set 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 */protected void prepareMethodOverride(MethodOverride mo) throws BeanDefinitionValidationException { // 获取对应类中对应方法名的个数 int count = ClassUtils.getMethodCountForName(getBeanClass(), mo.getMethodName()); if (count == 0) { throw new BeanDefinitionValidationException( "Invalid method override: no method with name '" + mo.getMethodName() + "' on class [" + getBeanClassName() + "]"); } else if (count == 1) { // 标记MethodOverride暂未被重载,避免参数类型检查的开销 mo.setOverloaded(false); }}
/** * 对BeanDefinition中的属性做些前置处理 * 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 */@Nullableprotected 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的实例化前会调用后处理器的方法进行处理 bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName); if (bean != null) { // 实例化后的后处理器应用 bean = applyBeanPostProcessorsAfterInitialization(bean, beanName); } } } mbd.beforeInstantiationResolved = (bean != null); } return bean;}
/** * Apply InstantiationAwareBeanPostProcessors to the specified bean definition * (by class and name), invoking their {@code postProcessBeforeInstantiation} methods. *
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 */@Nullableprotected 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;}
public class A { private B b; public A(B b) { this.b = b; }}public class B { private C c; public B(C c) { this.c = c; }}public class C { private A a; public C(A a) { this.a = a; }}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
Spring在创建 A 类时,构造器需要 B 类,那么将去创建 B;在创建 B 的时候,又发现需要 C 类,则又去创建 C 类;最终在创建 C 类的时候发现又需要 A,从而形成环,这种情况下Spring是无法解决的。
public class CircleDependencyTest { @Test public void testCircleDependency() { ClassPathResource resource = new ClassPathResource("circleDependency-Test.xml"); BeanFactory beanFactory = new XmlBeanFactory(resource); A a = (A) beanFactory.getBean("a"); }}
/** 一级缓存 */private final Map singletonObjects = new ConcurrentHashMap(256);/** 二级缓存 */private final Map earlySingletonObjects = new HashMap(16);/** 三级缓存 */private final Map=""???>> singletonFactories = new HashMap=""???>>(16);
public class D { private E e; public E getE() { return e; } public void setE(E e) { this.e = e; }}public class E { private F f; public F getF() { return f; } public void setF(F f) { this.f = f; }}public class F { private D d; public D getD() { return d; } public void setD(D d) { this.d = d; }}
/** * 真正创建常规bean的地方 * Actually create the specified bean. Pre-creation processing has already happened * at this point, e.g. checking {@code postProcessBeforeInstantiation} callbacks. *
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) { // 根据指定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) { // 应用MergedBeanDefinitionPostProcessors 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加入工厂 addSingletonFactory(beanName, // 对bean再一次依赖引用,主要应用SmartInstantiationAware BeanPostProcessor // 其中我们熟知的AOP就是这样将advice动态织入bean中,若没有则直接返回bean,不做任何处理 () -> 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 actualDependentBeans = new LinkedHashSet<>(dependentBeans.length); for (String dependentBean : dependentBeans) { // 检测依赖 if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) { actualDependentBeans.add(dependentBean); } } // 因为bean创建后其所依赖的bean一定是已经创建的 // actualDependentBeans不为空则表示当前bean创建后其依赖的bean却没有没全部创建完,也就是说存在循环依赖 if (!actualDependentBeans.isEmpty()) { throw new BeanCurrentlyInCreationException(beanName, "Bean with name '" + beanName + "' has been injected into other beans [" + StringUtils.collectionToCommaDelimitedString(actualDependentBeans) + "] in its raw version as part of a circular reference, but has eventually been " + "wrapped. This means that said other beans do not use the final version of the " + "bean. This is often the result of over-eager type matching - consider using " + "'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example."); } } } } // Register bean as disposable. try { // 根据scope注册bean registerDisposableBeanIfNecessary(beanName, bean, mbd); } catch (BeanDefinitionValidationException ex) { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex); } return exposedObject;}
/** * 带有参数的构造方法实例化 * "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. *
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 */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; } // 如果getBean方法调用的时候没有指定方法参数则尝试从缓存中解析 else { Object[] argsToResolve = null; // 尝试从缓存中获取 synchronized (mbd.constructorArgumentLock) { constructorToUse = (Constructor) mbd.resolvedConstructorOrFactoryMethod; if (constructorToUse != null && mbd.constructorArgumentsResolved) { // 从缓存中获取 argsToUse = mbd.resolvedConstructorArguments; if (argsToUse == null) { // 配置的构造函数参数 argsToResolve = mbd.preparedConstructorArguments; } } } // 如果缓存中存在 if (argsToResolve != null) { // 解析参数类型,如给定方法的构造函数A(int, int)则通过此方法后就会把配置中的("1", "1")转换为(1, 1) // 缓存中的值可能是原始值也可能是最终值 argsToUse = resolvePreparedArguments(beanName, mbd, bw, constructorToUse, argsToResolve); } } // 如果没有被缓存,则从配置文件的配置下手 if (constructorToUse == null) { // 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<>???>> ambiguousConstructors = null; LinkedList causes = null; for (Constructor candidate : candidates) { // 获取每个构造函数其所有的参数类型组成数组(不去重) Class[] paramTypes = candidate.getParameterTypes(); if (constructorToUse != null && argsToUse.length > paramTypes.length) { // 如果已经找到该用的构造函数并且用的参数大于构造函数可以传入的,因为降序排序,所以一旦大于,后面都会大于 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 (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 ArgumentsHolder(explicitArgs); } // 探测是否有不确定的构造函数存在,例如不同构造函数的参数为父子关系 int typeDiffWeight = (mbd.isLenientConstructorResolution() ? argsHolder.getTypeDifferenceWeight(paramTypes) : argsHolder.getAssignabilityWeight(paramTypes)); // 如果他代表着当前最接近的匹配则选择作为构造函数 if (typeDiffWeight < minTypeDiffWeight) { constructorToUse = candidate; argsHolderToUse = argsHolder; argsToUse = argsHolder.arguments; minTypeDiffWeight = typeDiffWeight; ambiguousConstructors = null; } else if (constructorToUse != null && typeDiffWeight == minTypeDiffWeight) { if (ambiguousConstructors == null) { ambiguousConstructors = new LinkedHashSet<>(); ambiguousConstructors.add(constructorToUse); } ambiguousConstructors.add(candidate); } } if (constructorToUse == null) { if (causes != null) { UnsatisfiedDependencyException ex = causes.removeLast(); for (Exception cause : causes) { this.beanFactory.onSuppressedException(cause); } throw ex; } throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Could not resolve matching constructor " + "(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities)"); } else if (ambiguousConstructors != null && !mbd.isLenientConstructorResolution()) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Ambiguous constructor matches found in bean '" + beanName + "' " + "(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities): " + ambiguousConstructors); } if (explicitArgs == null) { // 将解析的构造函数加入缓存 argsHolderToUse.storeCache(mbd, constructorToUse); } } try { final InstantiationStrategy strategy = this.beanFactory.getInstantiationStrategy(); Object beanInstance; if (System.getSecurityManager() != null) { final Constructor ctorToUse = constructorToUse; final Object[] argumentsToUse = argsToUse; beanInstance = AccessController.doPrivileged((PrivilegedAction
/** * 确定构造函数参数,并保存到resolvedValues中 * Resolve the constructor arguments for this bean into the resolvedValues object. * This may involve looking up other beans. *
This method is also used for handling invocations of static factory methods. * @param beanName bean名称 * @param mbd 配置文件信息 * @param bw beanwrapper * @param cargs 配置文件中解析出的构造函数信息 * @param resolvedValues 保存解析出的参数值信息 * @return 解析到参数的个数 */private int resolveConstructorArguments(String beanName, RootBeanDefinition mbd, BeanWrapper bw, ConstructorArgumentValues cargs, ConstructorArgumentValues resolvedValues) { TypeConverter customConverter = this.beanFactory.getCustomTypeConverter(); TypeConverter converter = (customConverter != null ? customConverter : bw); BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this.beanFactory, beanName, mbd, converter); int minNrOfArgs = cargs.getArgumentCount(); for (Map.Entry entry : cargs.getIndexedArgumentValues().entrySet()) { int index = entry.getKey(); if (index < 0) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid constructor argument index: " + index); } if (index > minNrOfArgs) { minNrOfArgs = index + 1; } ConstructorArgumentValues.ValueHolder valueHolder = entry.getValue(); if (valueHolder.isConverted()) { resolvedValues.addIndexedArgumentValue(index, valueHolder); } else { Object resolvedValue = valueResolver.resolveValueIfNecessary("constructor argument", valueHolder.getValue()); ConstructorArgumentValues.ValueHolder resolvedValueHolder = new ConstructorArgumentValues.ValueHolder(resolvedValue, valueHolder.getType(), valueHolder.getName()); resolvedValueHolder.setSource(valueHolder); resolvedValues.addIndexedArgumentValue(index, resolvedValueHolder); } } for (ConstructorArgumentValues.ValueHolder valueHolder : cargs.getGenericArgumentValues()) { if (valueHolder.isConverted()) { resolvedValues.addGenericArgumentValue(valueHolder); } else { Object resolvedValue = valueResolver.resolveValueIfNecessary("constructor argument", valueHolder.getValue()); ConstructorArgumentValues.ValueHolder resolvedValueHolder = new ConstructorArgumentValues.ValueHolder( resolvedValue, valueHolder.getType(), valueHolder.getName()); resolvedValueHolder.setSource(valueHolder); resolvedValues.addGenericArgumentValue(resolvedValueHolder); } } return minNrOfArgs;}
/* * 将确定的构造函数转换为对应的参数类型 * Create an array of arguments to invoke a constructor or factory method, * given the resolved constructor argument values. */private ArgumentsHolder createArgumentArray( String beanName, RootBeanDefinition mbd, @Nullable ConstructorArgumentValues resolvedValues, BeanWrapper bw, Class[] paramTypes, @Nullable String[] paramNames, Executable executable, boolean autowiring) throws UnsatisfiedDependencyException { TypeConverter customConverter = this.beanFactory.getCustomTypeConverter(); TypeConverter converter = (customConverter != null ? customConverter : bw); ArgumentsHolder args = new ArgumentsHolder(paramTypes.length); Set usedValueHolders = new HashSet<>(paramTypes.length); Set autowiredBeanNames = new LinkedHashSet<>(4); for (int paramIndex = 0; paramIndex < paramTypes.length; paramIndex++) { Class paramType = paramTypes[paramIndex]; String paramName = (paramNames != null ? paramNames[paramIndex] : ""); // Try to find matching constructor argument value, either indexed or generic. ConstructorArgumentValues.ValueHolder valueHolder = null; if (resolvedValues != null) { valueHolder = resolvedValues.getArgumentValue(paramIndex, paramType, paramName, usedValueHolders); // If we couldn't find a direct match and are not supposed to autowire, // let's try the next generic, untyped argument value as fallback: // it could match after type conversion (for example, String -> int). if (valueHolder == null && (!autowiring || paramTypes.length == resolvedValues.getArgumentCount())) { valueHolder = resolvedValues.getGenericArgumentValue(null, null, usedValueHolders); } } if (valueHolder != null) { // We found a potential match - let's give it a try. // Do not consider the same value definition multiple times! usedValueHolders.add(valueHolder); Object originalValue = valueHolder.getValue(); Object convertedValue; if (valueHolder.isConverted()) { convertedValue = valueHolder.getConvertedValue(); args.preparedArguments[paramIndex] = convertedValue; } else { MethodParameter methodParam = MethodParameter.forExecutable(executable, paramIndex); try { convertedValue = converter.convertIfNecessary(originalValue, paramType, methodParam); } catch (TypeMismatchException ex) { throw new UnsatisfiedDependencyException( mbd.getResourceDescription(), beanName, new InjectionPoint(methodParam), "Could not convert argument value of type [" + ObjectUtils.nullSafeClassName(valueHolder.getValue()) + "] to required type [" + paramType.getName() + "]: " + ex.getMessage()); } Object sourceHolder = valueHolder.getSource(); if (sourceHolder instanceof ConstructorArgumentValues.ValueHolder) { Object sourceValue = ((ConstructorArgumentValues.ValueHolder) sourceHolder).getValue(); args.resolveNecessary = true; args.preparedArguments[paramIndex] = sourceValue; } } args.arguments[paramIndex] = convertedValue; args.rawArguments[paramIndex] = originalValue; } else { MethodParameter methodParam = MethodParameter.forExecutable(executable, paramIndex); // No explicit match found: we're either supposed to autowire or // have to fail creating an argument array for the given constructor. if (!autowiring) { throw new UnsatisfiedDependencyException( mbd.getResourceDescription(), beanName, new InjectionPoint(methodParam), "Ambiguous argument values for parameter of type [" + paramType.getName() + "] - did you specify the correct bean references as arguments?"); } try { Object autowiredArgument = resolveAutowiredArgument(methodParam, beanName, autowiredBeanNames, converter); args.rawArguments[paramIndex] = autowiredArgument; args.arguments[paramIndex] = autowiredArgument; args.preparedArguments[paramIndex] = new AutowiredArgumentMarker(); args.resolveNecessary = true; } catch (BeansException ex) { throw new UnsatisfiedDependencyException( mbd.getResourceDescription(), beanName, new InjectionPoint(methodParam), ex); } } } for (String autowiredBeanName : autowiredBeanNames) { this.beanFactory.registerDependentBean(autowiredBeanName, beanName); if (logger.isDebugEnabled()) { logger.debug("Autowiring by type from bean name '" + beanName + "' via " + (executable instanceof Constructor ? "constructor" : "factory method") + " to bean named '" + autowiredBeanName + "'"); } } return args;}
/** * 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 */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;}
/** * 在传入的参数bw中,找出已经加载的bean,并递归实例化,进而加入到pvs中 * Fill in any missing property values with references to * other beans in this factory if autowire is set to "byName". * @param beanName the name of the bean we're wiring up. * Useful for debugging messages; not used functionally. * @param mbd bean definition to update through autowiring * @param bw the BeanWrapper from which we can obtain information about the bean * @param pvs the PropertyValues to register wired objects with */protected void autowireByName( String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) { // 寻找bw中需要依赖注入的属性 String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw); for (String propertyName : propertyNames) { if (containsBean(propertyName)) { // 递归初始化相关的bean Object bean = getBean(propertyName); pvs.add(propertyName, bean); // 注册依赖 registerDependentBean(propertyName, beanName); if (logger.isDebugEnabled()) { logger.debug("Added autowiring by name from bean name '" + beanName + "' via property '" + propertyName + "' to bean named '" + propertyName + "'"); } } else { if (logger.isTraceEnabled()) { logger.trace("Not autowiring property '" + propertyName + "' of bean '" + beanName + "' by name: no matching bean found"); } } }}
/** * 初始化bean-->用户配置的init-method * Initialize the given bean instance, applying factory callbacks * as well as init methods and bean post processors. *
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 #applyBeanPostProcessorsAfterInitialization */protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) { if (System.getSecurityManager() != null) { AccessController.doPrivileged((PrivilegedAction) () -> { invokeAwareMethods(beanName, bean); return null; }, getAccessControlContext()); } else { // 对特殊的bean的处理:BeanNameAware、BeanClassLoaderAware、BeanFactoryAware invokeAwareMethods(beanName, bean); } Object wrappedBean = bean; if (mbd == null || !mbd.isSynthetic()) { // 应用后处理器 wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); } try { // 激活用户自定义的init方法 invokeInitMethods(beanName, wrappedBean, mbd); } catch (Throwable ex) { throw new BeanCreationException( (mbd != null ? mbd.getResourceDescription() : null), beanName, "Invocation of init method failed", ex); } if (mbd == null || !mbd.isSynthetic()) { // 后处理应用 wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); } return wrappedBean;}
/** * 激活用户自定义初始化方法 * 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 { // 首先检查bean是否是InitializingBean实例,是的话需要先调用afterPropertiesSet方法 boolean isInitializingBean = (bean instanceof InitializingBean); if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) { if (logger.isDebugEnabled()) { logger.debug("Invoking afterPropertiesSet() on bean with name '" + beanName + "'"); } if (System.getSecurityManager() != null) { try { AccessController.doPrivileged((PrivilegedExceptionAction) () -> { ((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); } }}
/** * 注册DisposableBean,销毁方法的扩展入口 * 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. 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)); } }}