目录
代码块1:resolveBeforeInstantiation
代码块2:applyBeanPostProcessorsBeforeInstantiation
代码块4.5:determineConstructorsFromBeanPostProcessors
代码块6:resolveConstructorArguments
代码块16:determineAutowireCandidate
代码块17:determinePrimaryCandidate
代码块18:determineHighestPriorityCandidate
Spring IoC源码学习全系列
Spring IoC源码学习:ApplicationContext 刷新前的配置
Spring IoC源码学习:obtainFreshBeanFactory详解
Spring IoC源码学习:parseDefaultElement详解
Spring IoC源码学习:parseCustomElement详解
Spring IoC源码学习:context:component-scan节点详解
Spring IoC源码学习:invokeBeanFactoryPostProcessors详解
Spring IoC源码学习:registerBeanPostProcessors详解
Spring IoC源码学习:finishBeanFactoryInitialization详解
Spring IoC源码学习:createBean详解(上)
Spring IoC源码学习:createBean详解(下)
Spring IoC源码学习:finishRefresh详解
接着Spring IoC:getBean详解,我们继续解析获取 bean 实例里的核心内容:创建 bean 实例。
首先,我们进入 createBean 方法。
@Override protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException { if (logger.isDebugEnabled()) { logger.debug("Creating instance of bean '" + beanName + "'"); } RootBeanDefinition mbdToUse = mbd; // Make sure bean class is actually resolved at this point, and // clone the bean definition in case of a dynamically resolved Class // which cannot be stored in the shared merged bean definition. // 1.解析beanName对应的Bean的类型,例如:com.joonwhee.open.demo.service.impl.UserServiceImpl Class<?> resolvedClass = resolveBeanClass(mbd, beanName); if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) { // 如果resolvedClass存在,并且mdb的beanClass类型不是Class,并且mdb的beanClass不为空(则代表beanClass存的是Class的name), // 则使用mdb深拷贝一个新的RootBeanDefinition副本,并且将解析的Class赋值给拷贝的RootBeanDefinition副本的beanClass属性, // 该拷贝副本取代mdb用于后续的操作 mbdToUse = new RootBeanDefinition(mbd); mbdToUse.setBeanClass(resolvedClass); } // Prepare method overrides. try { // 2.验证及准备覆盖的方法(对override属性进行标记及验证) 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. // 3.实例化前的处理,给InstantiationAwareBeanPostProcessor一个机会返回代理对象来替代真正的bean实例,达到“短路”效果 Object bean = resolveBeforeInstantiation(beanName, mbdToUse); // 4.如果bean不为空,则会跳过Spring默认的实例化过程,直接使用返回的bean if (bean != null) { return bean; } } catch (Throwable ex) { throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "BeanPostProcessor before instantiation of bean failed", ex); } // 5.创建Bean实例(真正创建Bean的方法) Object beanInstance = doCreateBean(beanName, mbdToUse, args); if (logger.isDebugEnabled()) { logger.debug("Finished creating instance of bean '" + beanName + "'"); } // 6.返回创建的Bean实例 return beanInstance; }
3.实例化前的处理,给 InstantiationAwareBeanPostProcessor 一个机会返回代理对象来替代真正的 bean 实例,从而跳过 Spring 默认的实例化过程,达到“短路”效果,见代码块1详解。
5.创建 bean 实例,见代码块3详解。
代码块1:resolveBeforeInstantiation
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) { Object bean = null; if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) { // Make sure bean class is actually resolved at this point. // 1.mbd不是合成的,并且BeanFactory中存在InstantiationAwareBeanPostProcessor if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { // 2.解析beanName对应的Bean实例的类型 Class<?> targetType = determineTargetType(beanName, mbd); if (targetType != null) { // 3.实例化前的后置处理器应用(处理InstantiationAwareBeanPostProcessor) bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName); if (bean != null) { // 4.如果返回的bean不为空,会跳过Spring默认的实例化过程, // 所以只能在这里调用BeanPostProcessor实现类的postProcessAfterInitialization方法 bean = applyBeanPostProcessorsAfterInitialization(bean, beanName); } } } // 5.如果bean不为空,则将beforeInstantiationResolved赋值为true,代表在实例化之前已经解析 mbd.beforeInstantiationResolved = (bean != null); } return bean; }
3.实例化前的后置处理器应用,见代码块2详解。
4.实例化后的后置处理器应用,见Spring IoC:getBean详解中的代码块4。
代码块2:applyBeanPostProcessorsBeforeInstantiation
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) { // 1.遍历当前BeanFactory中的BeanPostProcessor for (BeanPostProcessor bp : getBeanPostProcessors()) { // 2.应用InstantiationAwareBeanPostProcessor后置处理器,允许postProcessBeforeInstantiation方法返回bean对象的代理 if (bp instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; // 3.执行postProcessBeforeInstantiation方法,在Bean实例化前操作, // 该方法可以返回一个构造完成的Bean实例,从而不会继续执行创建Bean实例的“正规的流程”,达到“短路”的效果。 Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName); if (result != null) { // 4.如果result不为空,也就是有后置处理器返回了bean实例对象,则会跳过Spring默认的实例化过程 return result; } } } return null; }
在实例化之前执行 InstantiationAwareBeanPostProcessor 的postProcessBeforeInstantiation 方法,该方法可以返回 bean 实例的代理,从而跳过 Spring 默认的实例化过程。
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) throws BeanCreationException { // Instantiate the bean. // 1.新建Bean包装类 BeanWrapper instanceWrapper = null; if (mbd.isSingleton()) { // 2.如果是FactoryBean,则需要先移除未完成的FactoryBean实例的缓存 instanceWrapper = this.factoryBeanInstanceCache.remove(beanName); } if (instanceWrapper == null) { // 3.根据beanName、mbd、args,使用对应的策略创建Bean实例,并返回包装类BeanWrapper instanceWrapper = createBeanInstance(beanName, mbd, args); } // 4.拿到创建好的Bean实例 final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null); // 5.拿到Bean实例的类型 Class<?> beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null); mbd.resolvedTargetType = beanType; // Allow post-processors to modify the merged bean definition. synchronized (mbd.postProcessingLock) { if (!mbd.postProcessed) { try { // 6.应用后置处理器MergedBeanDefinitionPostProcessor,允许修改MergedBeanDefinition, // Autowired注解正是通过此方法实现注入类型的预解析 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. // 7.判断是否需要提早曝光实例:单例 && 允许循环依赖 && 当前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"); } // 8.提前曝光beanName的ObjectFactory,用于解决循环引用 addSingletonFactory(beanName, new ObjectFactory<Object>() { @Override public Object getObject() throws BeansException { // 8.1 应用后置处理器SmartInstantiationAwareBeanPostProcessor,允许返回指定bean的早期引用,若没有则直接返回bean return getEarlyBeanReference(beanName, mbd, bean); } }); } // Initialize the bean instance. 初始化bean实例。 Object exposedObject = bean; try { // 9.对bean进行属性填充;其中,可能存在依赖于其他bean的属性,则会递归初始化依赖的bean实例 populateBean(beanName, mbd, instanceWrapper); if (exposedObject != null) { // 10.对bean进行初始化 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) { // 11.如果允许提前曝光实例,则进行循环依赖检查 Object earlySingletonReference = getSingleton(beanName, false); // 11.1 earlySingletonReference只有在当前解析的bean存在循环依赖的情况下才会不为空 if (earlySingletonReference != null) { if (exposedObject == bean) { // 11.2 如果exposedObject没有在initializeBean方法中被增强,则不影响之前的循环引用 exposedObject = earlySingletonReference; } else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) { // 11.3 如果exposedObject在initializeBean方法中被增强 && 不允许在循环引用的情况下使用注入原始bean实例 // && 当前bean有被其他bean依赖 // 11.4 拿到依赖当前bean的所有bean的beanName数组 String[] dependentBeans = getDependentBeans(beanName); Set<String> actualDependentBeans = new LinkedHashSet<String>(dependentBeans.length); for (String dependentBean : dependentBeans) { // 11.5 尝试移除这些bean的实例,因为这些bean依赖的bean已经被增强了,他们依赖的bean相当于脏数据 if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) { // 11.6 移除失败的添加到 actualDependentBeans actualDependentBeans.add(dependentBean); } } if (!actualDependentBeans.isEmpty()) { // 11.7 如果存在移除失败的,则抛出异常,因为存在bean依赖了“脏数据” 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 { // 12.注册用于销毁的bean,执行销毁操作的有三种:自定义destroy方法、DisposableBean接口、DestructionAwareBeanPostProcessor registerDisposableBeanIfNecessary(beanName, bean, mbd); } catch (BeanDefinitionValidationException ex) { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex); } // 13.完成创建并返回 return exposedObject; }
真正创建 bean 实例的方法,整个系列文章中的核心中的核心,很多代码是前后相关联的,需要反复阅读才能很好的理解。
3.根据 beanName、mbd、args,使用对应的策略创建 bean 实例,并返回包装类 BeanWrapper,见代码块4详解。
由于创建 bean 实例的过程过长,限于篇幅关系,本文只介绍第 3 点的 createBeanInstance 方法,剩余的内容将在下一篇文章介绍。
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) { // Make sure bean class is actually resolved at this point. // 解析bean的类型信息 Class<?> beanClass = resolveBeanClass(mbd, beanName); if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) { // beanClass不为空 && beanClass不是公开类(不是public修饰) && 该bean不允许访问非公共构造函数和方法,则抛异常 throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Bean class isn't public, and non-public access not allowed: " + beanClass.getName()); } // 1.如果存在工厂方法则使用工厂方法实例化bean对象 if (mbd.getFactoryMethodName() != null) { return instantiateUsingFactoryMethod(beanName, mbd, args); } // Shortcut when re-creating the same bean... // resolved: 构造函数或工厂方法是否已经解析过 boolean resolved = false; // autowireNecessary: 是否需要自动注入(即是否需要解析构造函数参数) boolean autowireNecessary = false; if (args == null) { // 2.加锁 synchronized (mbd.constructorArgumentLock) { if (mbd.resolvedConstructorOrFactoryMethod != null) { // 2.1 如果resolvedConstructorOrFactoryMethod缓存不为空,则将resolved标记为已解析 resolved = true; // 2.2 根据constructorArgumentsResolved判断是否需要自动注入 autowireNecessary = mbd.constructorArgumentsResolved; } } } if (resolved) { // 3.如果已经解析过,则使用resolvedConstructorOrFactoryMethod缓存里解析好的构造函数方法 if (autowireNecessary) { // 3.1 需要自动注入,则执行构造函数自动注入 return autowireConstructor(beanName, mbd, null, null); } else { // 3.2 否则使用默认的构造函数进行bean的实例化 return instantiateBean(beanName, mbd); } } // Need to determine the constructor... // 4.应用后置处理器SmartInstantiationAwareBeanPostProcessor,拿到bean的候选构造函数 Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName); if (ctors != null || mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR || mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) { // 5.如果ctors不为空 || mbd的注入方式为AUTOWIRE_CONSTRUCTOR || mdb定义了构造函数的参数值 || args不为空,则执行构造函数自动注入 return autowireConstructor(beanName, mbd, ctors, args); } // No special handling: simply use no-arg constructor. // 6.没有特殊处理,则使用默认的构造函数进行bean的实例化 return instantiateBean(beanName, mbd); }
创建实例的方法通常有以下几种:工厂方法、构造函数自动装配(通常指带有参数的构造函数)、简单实例化(默认的构造函数)。其中工厂方法现在基本不使用了,不再解析;简单实例化过程比较简单,也不解析;本文只对构造函数自动装配进行解析,该方法对应代码中的:3.1 和 5。
4.应用后置处理器 SmartInstantiationAwareBeanPostProcessor,拿到给定bean 的候选构造函数,见代码块4.5详解。
5.执行构造函数自动注入,见代码块5详解。
代码块4.5:determineConstructorsFromBeanPostProcessors
protected Constructor<?>[] determineConstructorsFromBeanPostProcessors(Class<?> beanClass, String beanName) throws BeansException { if (beanClass != null && hasInstantiationAwareBeanPostProcessors()) { // 1.遍历所有的BeanPostProcessor for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof SmartInstantiationAwareBeanPostProcessor) { SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp; // 2.调用SmartInstantiationAwareBeanPostProcessor的determineCandidateConstructors方法, // 该方法可以返回要用于beanClass的候选构造函数 // 例如:使用@Autowire注解修饰构造函数,则该构造函数在这边会被AutowiredAnnotationBeanPostProcessor找到 Constructor<?>[] ctors = ibp.determineCandidateConstructors(beanClass, beanName); if (ctors != null) { // 3.如果ctors不为空,则不再继续执行其他的SmartInstantiationAwareBeanPostProcessor return ctors; } } } } return null; }
2.调用 SmartInstantiationAwareBeanPostProcessor 的determineCandidateConstructors 方法,该方法可以返回要用于 beanClass 的候选构造函数。使用 @Autowire 注解修饰构造函数,则该构造函数在这边会被AutowiredAnnotationBeanPostProcessor 找到,该内容会在之后介绍 @Autowire 的文章中单独介绍。
protected BeanWrapper autowireConstructor( String beanName, RootBeanDefinition mbd, Constructor<?>[] ctors, Object[] explicitArgs) { return new ConstructorResolver(this).autowireConstructor(beanName, mbd, ctors, explicitArgs); } public BeanWrapper autowireConstructor(final String beanName, final RootBeanDefinition mbd, Constructor<?>[] chosenCtors, final Object[] explicitArgs) { // 定义bean包装类 BeanWrapperImpl bw = new BeanWrapperImpl(); this.beanFactory.initBeanWrapper(bw); // 最终用于实例化的构造函数 Constructor<?> constructorToUse = null; // 最终用于实例化的参数Holder ArgumentsHolder argsHolderToUse = null; // 最终用于实例化的构造函数参数 Object[] argsToUse = null; // 1.解析出要用于实例化的构造函数参数 if (explicitArgs != null) { // 1.1 如果explicitArgs不为空,则构造函数的参数直接使用explicitArgs // 通过getBean方法调用时,显示指定了参数,则explicitArgs就不为null argsToUse = explicitArgs; } else { // 1.2 尝试从缓存中获取已经解析过的构造函数参数 Object[] argsToResolve = null; synchronized (mbd.constructorArgumentLock) { // 1.2.1 拿到缓存中已解析的构造函数或工厂方法 constructorToUse = (Constructor<?>) mbd.resolvedConstructorOrFactoryMethod; // 1.2.2 如果constructorToUse不为空 && mbd标记了构造函数参数已解析 if (constructorToUse != null && mbd.constructorArgumentsResolved) { // Found a cached constructor... // 1.2.3 从缓存中获取已解析的构造函数参数 argsToUse = mbd.resolvedConstructorArguments; if (argsToUse == null) { // 1.2.4 如果resolvedConstructorArguments为空,则从缓存中获取准备用于解析的构造函数参数, // constructorArgumentsResolved为true时,resolvedConstructorArguments和 // preparedConstructorArguments必然有一个缓存了构造函数的参数 argsToResolve = mbd.preparedConstructorArguments; } } } if (argsToResolve != null) { // 1.2.5 如果argsToResolve不为空,则对构造函数参数进行解析, // 如给定方法的构造函数 A(int,int)则通过此方法后就会把配置中的("1","1")转换为(1,1) argsToUse = resolvePreparedArguments(beanName, mbd, bw, constructorToUse, argsToResolve); } } // 2.如果构造函数没有被缓存,则通过配置文件获取 if (constructorToUse == null) { // Need to resolve the constructor. // 2.1 检查是否需要自动装配:chosenCtors不为空 || autowireMode为AUTOWIRE_CONSTRUCTOR // 例子:当chosenCtors不为空时,代表有构造函数通过@Autowire修饰,因此需要自动装配 boolean autowiring = (chosenCtors != null || mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR); ConstructorArgumentValues resolvedValues = null; // 构造函数参数个数 int minNrOfArgs; if (explicitArgs != null) { // 2.2 explicitArgs不为空,则使用explicitArgs的length作为minNrOfArgs的值 minNrOfArgs = explicitArgs.length; } else { // 2.3 获得mbd的构造函数的参数值(indexedArgumentValues:带index的参数值;genericArgumentValues:通用的参数值) ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues(); // 2.4 创建ConstructorArgumentValues对象resolvedValues,用于承载解析后的构造函数参数的值 resolvedValues = new ConstructorArgumentValues(); // 2.5 解析mbd的构造函数的参数,并返回参数个数 minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues); // 注:这边解析mbd中的构造函数参数值,主要是处理我们通过xml方式定义的构造函数注入的参数, // 但是如果我们是通过@Autowire注解直接修饰构造函数,则mbd是没有这些参数值的 } // 3.确认构造函数的候选者 // Take specified constructors, if any. // 3.1 如果入参chosenCtors不为空,则将chosenCtors的构造函数作为候选者 Constructor<?>[] candidates = chosenCtors; if (candidates == null) { Class<?> beanClass = mbd.getBeanClass(); try { // 3.2 如果入参chosenCtors为空,则获取beanClass的构造函数 // (mbd是否允许访问非公共构造函数和方法 ? 所有声明的构造函数:公共构造函数) 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); } } // 3.3 对给定的构造函数排序:先按方法修饰符排序:public排非public前面,再按构造函数参数个数排序:参数多的排前面 AutowireUtils.sortConstructors(candidates); // 最小匹配权重,权重越小,越接近我们要找的目标构造函数 int minTypeDiffWeight = Integer.MAX_VALUE; Set<Constructor<?>> ambiguousConstructors = null; LinkedList<UnsatisfiedDependencyException> causes = null; // 4.遍历所有构造函数候选者,找出符合条件的构造函数 for (Constructor<?> candidate : candidates) { // 4.1 拿到当前遍历的构造函数的参数类型数组 Class<?>[] paramTypes = candidate.getParameterTypes(); if (constructorToUse != null && argsToUse.length > paramTypes.length) { // Already found greedy constructor that can be satisfied -> // do not look any further, there are only less greedy constructors left. // 4.2 如果已经找到满足的构造函数 && 目标构造函数需要的参数个数大于当前遍历的构造函数的参数个数则终止, // 因为遍历的构造函数已经排过序,后面不会有更合适的候选者了 break; } if (paramTypes.length < minNrOfArgs) { // 4.3 如果当前遍历到的构造函数的参数个数小于我们所需的参数个数,则直接跳过该构造函数 continue; } ArgumentsHolder argsHolder; if (resolvedValues != null) { // 存在参数则根据参数值来匹配参数类型 try { // 4.4 resolvedValues不为空, // 4.4.1 获取当前遍历的构造函数的参数名称 // 4.4.1.1 解析使用ConstructorProperties注解的构造函数参数 String[] paramNames = ConstructorPropertiesChecker.evaluate(candidate, paramTypes.length); if (paramNames == null) { // 4.4.1.2 获取参数名称解析器 ParameterNameDiscoverer pnd = this.beanFactory.getParameterNameDiscoverer(); if (pnd != null) { // 4.4.1.3 使用参数名称解析器获取当前遍历的构造函数的参数名称 paramNames = pnd.getParameterNames(candidate); } } // 4.4.2 创建一个参数数组以调用构造函数或工厂方法, // 主要是通过参数类型和参数名解析构造函数或工厂方法所需的参数(如果参数是其他bean,则会解析依赖的bean) argsHolder = createArgumentArray(beanName, mbd, resolvedValues, bw, paramTypes, paramNames, getUserDeclaredConstructor(candidate), autowiring); } catch (UnsatisfiedDependencyException ex) { // 4.4.3 参数匹配失败,则抛出异常 if (this.beanFactory.logger.isTraceEnabled()) { this.beanFactory.logger.trace( "Ignoring constructor [" + candidate + "] of bean '" + beanName + "': " + ex); } // Swallow and try next constructor. if (causes == null) { causes = new LinkedList<UnsatisfiedDependencyException>(); } causes.add(ex); continue; } } else { // 4.5 resolvedValues为空,则explicitArgs不为空,即给出了显式参数 // Explicit arguments given -> arguments length must match exactly. // 4.5.1 如果当前遍历的构造函数参数个数与explicitArgs长度不相同,则跳过该构造函数 if (paramTypes.length != explicitArgs.length) { continue; } // 4.5.2 使用显式给出的参数构造ArgumentsHolder argsHolder = new ArgumentsHolder(explicitArgs); } // 4.6 根据mbd的解析构造函数模式(true: 宽松模式(默认),false:严格模式), // 将argsHolder的参数和paramTypes进行比较,计算paramTypes的类型差异权重值 int typeDiffWeight = (mbd.isLenientConstructorResolution() ? argsHolder.getTypeDifferenceWeight(paramTypes) : argsHolder.getAssignabilityWeight(paramTypes)); // Choose this constructor if it represents the closest match. // 4.7 类型差异权重值越小,则说明构造函数越匹配,则选择此构造函数 if (typeDiffWeight < minTypeDiffWeight) { // 将要使用的参数都替换成差异权重值更小的 constructorToUse = candidate; argsHolderToUse = argsHolder; argsToUse = argsHolder.arguments; minTypeDiffWeight = typeDiffWeight; // 如果出现权重值更小的候选者,则将ambiguousConstructors清空,允许之前存在权重值相同的候选者 ambiguousConstructors = null; } // 4.8 如果存在两个候选者的权重值相同,并且是当前遍历过权重值最小的 else if (constructorToUse != null && typeDiffWeight == minTypeDiffWeight) { // 将这两个候选者都添加到ambiguousConstructors if (ambiguousConstructors == null) { ambiguousConstructors = new LinkedHashSet<Constructor<?>>(); ambiguousConstructors.add(constructorToUse); } ambiguousConstructors.add(candidate); } } if (constructorToUse == null) { // 5.如果最终没有找到匹配的构造函数,则进行异常处理 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()) { // 6.如果找到了匹配的构造函数,但是存在多个(ambiguousConstructors不为空) && 解析构造函数的模式为严格模式,则抛出异常 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) { // 7.将解析的构造函数和参数放到缓存 argsHolderToUse.storeCache(mbd, constructorToUse); } } try { Object beanInstance; // 8.根据实例化策略以及得到的构造函数及构造函数参数实例化bean if (System.getSecurityManager() != null) { final Constructor<?> ctorToUse = constructorToUse; final Object[] argumentsToUse = argsToUse; beanInstance = AccessController.doPrivileged(new PrivilegedAction<Object>() { @Override public Object run() { return beanFactory.getInstantiationStrategy().instantiate( mbd, beanName, beanFactory, ctorToUse, argumentsToUse); } }, beanFactory.getAccessControlContext()); } else { beanInstance = this.beanFactory.getInstantiationStrategy().instantiate( mbd, beanName, this.beanFactory, constructorToUse, argsToUse); } // 9.将构造的实例加入BeanWrapper中,并返回 bw.setBeanInstance(beanInstance); return bw; } catch (Throwable ex) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Bean instantiation via constructor failed", ex); } }
例子:
这边2.3 - 2.5 解析的 mbd 的构造函数参数值主要是针对通过 XML 注入的方式,例如以下例子:
sping 配置文件:
<bean class="com.joonwhee.open.demo.service.impl.DemoServiceImpl"> <constructor-arg index="2" name="name" value="joonwhee"/> <constructor-arg name="age" value="25"/> <constructor-arg name="skillList"> <list> <value>sing</value> <value>basketball</value> </list> </constructor-arg> <constructor-arg index="0" name="id" value="1"/> <constructor-arg name="userService" ref="userService"/> </bean> <bean id="userService" class="com.joonwhee.open.demo.service.impl.UserServiceImpl"/>
构造函数参数中带 index 的会被解析到 ConstructorArgumentValues.indexedArgumentValues,不带的会被解析到 ConstructorArgumentValues.genericArgumentValues。
DemoServiceImpl.java
@Service public class DemoServiceImpl implements DemoService { private Integer id; private Integer age; private String name; private List<String> skillList; private UserService userService; public DemoServiceImpl(Integer id, Integer age, String name, List<String> skillList, UserService userService) { this.id = id; this.age = age; this.name = name; this.skillList = skillList; this.userService = userService; } @Override public void sayHello() { } }
2.5 解析 mbd 的构造函数的参数,并返回参数个数,见代码块6详解。
4.4.2 创建一个参数数组以调用构造函数或工厂方法,主要是通过参数类型和参数名解析构造函数或工厂方法所需的参数(如果参数是其他 bean,则会解析依赖的 bean),见代码块7详解。
7.将解析的构造函数和参数放到缓存,见代码块19详解。
代码块6:resolveConstructorArguments
private int resolveConstructorArguments(String beanName, RootBeanDefinition mbd, BeanWrapper bw, ConstructorArgumentValues cargs, ConstructorArgumentValues resolvedValues) { // 1.构建bean定义值解析器 TypeConverter customConverter = this.beanFactory.getCustomTypeConverter(); TypeConverter converter = (customConverter != null ? customConverter : bw); BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this.beanFactory, beanName, mbd, converter); // 2.minNrOfArgs初始化为indexedArgumentValues和genericArgumentValues的的参数个数总和 int minNrOfArgs = cargs.getArgumentCount(); // 3.遍历解析带index的参数值 for (Map.Entry<Integer, ConstructorArgumentValues.ValueHolder> entry : cargs.getIndexedArgumentValues().entrySet()) { int index = entry.getKey(); if (index < 0) { // index从0开始,不允许小于0 throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid constructor argument index: " + index); } // 3.1 如果index大于minNrOfArgs,则修改minNrOfArgs if (index > minNrOfArgs) { // index是从0开始,并且是有序递增的,所以当有参数的index=5时,代表该方法至少有6个参数 minNrOfArgs = index + 1; } ConstructorArgumentValues.ValueHolder valueHolder = entry.getValue(); // 3.2 解析参数值 if (valueHolder.isConverted()) { // 3.2.1 如果参数值已经转换过,则直接将index和valueHolder添加到resolvedValues的indexedArgumentValues属性 resolvedValues.addIndexedArgumentValue(index, valueHolder); } else { // 3.2.2 如果值还未转换过,则先进行转换 Object resolvedValue = valueResolver.resolveValueIfNecessary("constructor argument", valueHolder.getValue()); // 3.2.3 使用转换后的resolvedValue构建新的ValueHolder ConstructorArgumentValues.ValueHolder resolvedValueHolder = new ConstructorArgumentValues.ValueHolder(resolvedValue, valueHolder.getType(), valueHolder.getName()); // 3.2.4 将转换前的valueHolder保存到新的ValueHolder的source属性 resolvedValueHolder.setSource(valueHolder); // 3.2.5 将index和新的ValueHolder添加到resolvedValues的indexedArgumentValues属性 resolvedValues.addIndexedArgumentValue(index, resolvedValueHolder); } } // 4.遍历解析通用参数值(不带index) for (ConstructorArgumentValues.ValueHolder valueHolder : cargs.getGenericArgumentValues()) { if (valueHolder.isConverted()) { // 4.1 如果参数值已经转换过,则直接将valueHolder添加到resolvedValues的genericArgumentValues属性 resolvedValues.addGenericArgumentValue(valueHolder); } else { // 4.2 如果值还未转换过,则先进行转换 Object resolvedValue = valueResolver.resolveValueIfNecessary("constructor argument", valueHolder.getValue()); // 4.3 使用转换后的resolvedValue构建新的ValueHolder ConstructorArgumentValues.ValueHolder resolvedValueHolder = new ConstructorArgumentValues.ValueHolder(resolvedValue, valueHolder.getType(), valueHolder.getName()); // 4.4 将转换前的valueHolder保存到新的ValueHolder的source属性 resolvedValueHolder.setSource(valueHolder); // 4.5 将新的ValueHolder添加到resolvedValues的genericArgumentValues属性 resolvedValues.addGenericArgumentValue(resolvedValueHolder); } } // 5.返回构造函数参数的个数 return minNrOfArgs; }
private ArgumentsHolder createArgumentArray( String beanName, RootBeanDefinition mbd, ConstructorArgumentValues resolvedValues, BeanWrapper bw, Class<?>[] paramTypes, String[] paramNames, Object methodOrCtor, boolean autowiring) throws UnsatisfiedDependencyException { TypeConverter customConverter = this.beanFactory.getCustomTypeConverter(); // 获取类型转换器 TypeConverter converter = (customConverter != null ? customConverter : bw); // 新建一个ArgumentsHolder来存放匹配到的参数 ArgumentsHolder args = new ArgumentsHolder(paramTypes.length); Set<ConstructorArgumentValues.ValueHolder> usedValueHolders = new HashSet<ConstructorArgumentValues.ValueHolder>(paramTypes.length); Set<String> autowiredBeanNames = new LinkedHashSet<String>(4); // 1.遍历参数类型数组 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. // 2.查找当前遍历的参数,是否在mdb对应的bean的构造函数参数中存在index、类型和名称匹配的 ConstructorArgumentValues.ValueHolder 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). // 3.如果我们找不到直接匹配并且不应该自动装配,那么让我们尝试下一个通用的无类型参数值作为降级方法:它可以在类型转换后匹配(例如,String - > int)。 if (valueHolder == null && (!autowiring || paramTypes.length == resolvedValues.getArgumentCount())) { valueHolder = resolvedValues.getGenericArgumentValue(null, null, usedValueHolders); } if (valueHolder != null) { // 4.valueHolder不为空,存在匹配的参数 // We found a potential match - let's give it a try. // Do not consider the same value definition multiple times! // 将valueHolder添加到usedValueHolders usedValueHolders.add(valueHolder); // 原始属性值 Object originalValue = valueHolder.getValue(); // 转换后的属性值 Object convertedValue; if (valueHolder.isConverted()) { // 4.1 如果valueHolder已经转换过 // 4.1.1 则直接获取转换后的值 convertedValue = valueHolder.getConvertedValue(); // 4.1.2 将convertedValue作为args在paramIndex位置的预备参数 args.preparedArguments[paramIndex] = convertedValue; } else { // 4.2 如果valueHolder还未转换过 // 4.2.1 拿到原始的ValueHolder ConstructorArgumentValues.ValueHolder sourceHolder = (ConstructorArgumentValues.ValueHolder) valueHolder.getSource(); // 4.2.2 拿到原始参数值 Object sourceValue = sourceHolder.getValue(); // 4.2.3 将方法(此处为构造函数)和参数索引封装成MethodParameter(MethodParameter是封装方法和参数索引的工具类) MethodParameter methodParam = MethodParameter.forMethodOrConstructor(methodOrCtor, paramIndex); try { // 4.2.4 将原始值转换为paramType类型的值(如果类型无法转,抛出TypeMismatchException) convertedValue = converter.convertIfNecessary(originalValue, paramType, methodParam); // TODO re-enable once race condition has been found (SPR-7423) /* if (originalValue == sourceValue || sourceValue instanceof TypedStringValue) { // Either a converted value or still the original one: store converted value. sourceHolder.setConvertedValue(convertedValue); args.preparedArguments[paramIndex] = convertedValue; } else { */ // 4.2.5 args标记为需要解析 args.resolveNecessary = true; // 4.2.6 将convertedValue作为args在paramIndex位置的预备参数 args.preparedArguments[paramIndex] = sourceValue; // } } catch (TypeMismatchException ex) { // 4.2.7 如果类型转换失败,则抛出异常 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()); } } // 4.3 将convertedValue作为args在paramIndex位置的参数 args.arguments[paramIndex] = convertedValue; // 4.4 将originalValue作为args在paramIndex位置的原始参数 args.rawArguments[paramIndex] = originalValue; } else { // 5.valueHolder为空,不存在匹配的参数 // 5.1 将方法(此处为构造函数)和参数索引封装成MethodParameter MethodParameter methodParam = MethodParameter.forMethodOrConstructor(methodOrCtor, paramIndex); // No explicit match found: we're either supposed to autowire or // have to fail creating an argument array for the given constructor. // 5.2 找不到明确的匹配,并且不是自动装配,则抛出异常 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 { // 5.3 如果是自动装配,则调用用于解析自动装配参数的方法,返回的结果为依赖的bean实例对象 // 例如:@Autowire修饰构造函数,自动注入构造函数中的参数bean就是在这边处理 Object autowiredArgument = resolveAutowiredArgument(methodParam, beanName, autowiredBeanNames, converter); // 5.4 将通过自动装配解析出来的参数赋值给args args.rawArguments[paramIndex] = autowiredArgument; args.arguments[paramIndex] = autowiredArgument; args.preparedArguments[paramIndex] = new AutowiredArgumentMarker(); args.resolveNecessary = true; } catch (BeansException ex) { // 5.5 如果自动装配解析失败,则会抛出异常 throw new UnsatisfiedDependencyException( mbd.getResourceDescription(), beanName, new InjectionPoint(methodParam), ex); } } } // 6.如果依赖了其他的bean,则注册依赖关系 for (String autowiredBeanName : autowiredBeanNames) { this.beanFactory.registerDependentBean(autowiredBeanName, beanName); if (this.beanFactory.logger.isDebugEnabled()) { this.beanFactory.logger.debug("Autowiring by type from bean name '" + beanName + "' via " + (methodOrCtor instanceof Constructor ? "constructor" : "factory method") + " to bean named '" + autowiredBeanName + "'"); } } return args; }
5.3 如果是自动装配,则调用用于解析自动装配参数的方法,返回的结果为依赖的bean 实例对象,见代码块8详解。
@Override public Object resolveDependency(DependencyDescriptor descriptor, String requestingBeanName, Set<String> autowiredBeanNames, TypeConverter typeConverter) throws BeansException { descriptor.initParameterNameDiscovery(getParameterNameDiscoverer()); if (javaUtilOptionalClass == descriptor.getDependencyType()) { // 1.javaUtilOptionalClass类注入的特殊处理 return new OptionalDependencyFactory().createOptionalDependency(descriptor, requestingBeanName); } else if (ObjectFactory.class == descriptor.getDependencyType() || // 2.ObjectFactory类注入的特殊处理 ObjectProvider.class == descriptor.getDependencyType()) { return new DependencyObjectProvider(descriptor, requestingBeanName); } else if (javaxInjectProviderClass == descriptor.getDependencyType()) { // 3.javaxInjectProviderClass类注入的特殊处理 return new Jsr330ProviderFactory().createDependencyProvider(descriptor, requestingBeanName); } else { // 4.通用类注入的处理 // 4.1 如有必要,请获取延迟解析代理 Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary( descriptor, requestingBeanName); if (result == null) { // 4.2 解析依赖关系,返回的result为创建好的依赖对象的bean实例 result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter); } return result; } }
4.2 解析依赖关系,返回的 result 为创建好的依赖对象的 bean 实例,见代码块10详解。
public Object doResolveDependency(DependencyDescriptor descriptor, String beanName, Set<String> autowiredBeanNames, TypeConverter typeConverter) throws BeansException { // 1.设置当前的descriptor(存储了方法参数等信息)为当前注入点 InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor); try { // 2.如果是ShortcutDependencyDescriptor,则直接通过getBean方法获取Bean实例,并返回;否则返回null Object shortcut = descriptor.resolveShortcut(this); if (shortcut != null) { return shortcut; } // 3.拿到descriptor包装的方法的参数类型(通过参数索引定位到具体的参数) Class<?> type = descriptor.getDependencyType(); // 4.用于支持spring中新增的注解@Value(确定给定的依赖项是否声明Value注解,如果有则拿到值) Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor); if (value != null) { if (value instanceof String) { String strVal = resolveEmbeddedValue((String) value); BeanDefinition bd = (beanName != null && containsBean(beanName) ? getMergedBeanDefinition(beanName) : null); value = evaluateBeanDefinitionString(strVal, bd); } TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter()); // 4.1 如果使用了@Value注解,则将解析到的值转换成所需的类型并返回 return (descriptor.getField() != null ? converter.convertIfNecessary(value, type, descriptor.getField()) : converter.convertIfNecessary(value, type, descriptor.getMethodParameter())); } // 5.解析MultipleBean(下文的MultipleBean都是指类型为:Array、Collection、Map) Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter); if (multipleBeans != null) { // 5.1 如果确实是容器类型的属性,则直接返回解析结果 return multipleBeans; } // 6.查找与所需类型匹配的Bean实例(matchingBeans,key:beanName;value:匹配的bean实例,或者匹配的bean实例的类型) Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor); if (matchingBeans.isEmpty()) { // 6.1 如果require属性为true,而找到的匹配Bean却为空则抛出异常 if (isRequired(descriptor)) { raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor); } // 6.2 如果require属性为false,而找到的匹配Bean却为空,则返回nul return null; } String autowiredBeanName; Object instanceCandidate; if (matchingBeans.size() > 1) { // 7.非MultipleBean,但是有多个候选者 // 7.1 从多个候选者中选出最优的那个 autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor); if (autowiredBeanName == null) { if (isRequired(descriptor) || !indicatesMultipleBeans(type)) { return descriptor.resolveNotUnique(type, matchingBeans); } else { // In case of an optional Collection/Map, silently ignore a non-unique case: // possibly it was meant to be an empty collection of multiple regular beans // (before 4.3 in particular when we didn't even look for collection beans). return null; } } // 7.2.拿到autowiredBeanName对应的value(bean实例或bean实例类型) instanceCandidate = matchingBeans.get(autowiredBeanName); } else { // 8.只找到了一个候选者,则直接使用该候选者 Map.Entry<String, Object> entry = matchingBeans.entrySet().iterator().next(); autowiredBeanName = entry.getKey(); instanceCandidate = entry.getValue(); } if (autowiredBeanNames != null) { // 9.将依赖的beanName加到autowiredBeanNames中 autowiredBeanNames.add(autowiredBeanName); } // 10.如果instanceCandidate为Class,则instanceCandidate为bean实例的类型,执行descriptor.resolveCandidate方法, // 通过getBean方法获取bean实例并返回;如果instanceCandidate不是Class,则instanceCandidate为bean实例,直接返回该实例 return (instanceCandidate instanceof Class ? descriptor.resolveCandidate(autowiredBeanName, type, this) : instanceCandidate); } finally { // 11.执行结束,将注入点修改成原来的注入点 ConstructorResolver.setCurrentInjectionPoint(previousInjectionPoint); } }
2.如果是 ShortcutDependencyDescriptor,则直接通过getBean 方法获取 bean 实例,并返回;否则返回 null。
通过构造函数注入依赖的 bean 实例的整个过程是不会出现涉及到ShortcutDependencyDescriptor 的。ShortcutDependencyDescriptor 主要用于 @Autowire注解,在解析 @Autowire 注解的时候,当第一次注入依赖的 bean 实例后,会将该依赖的 bean 的信息封装成 ShortcutDependencyDescriptor ,放到缓存中去,下一次需要依赖注入该 bean 时,可以直接快速的拿到该 bean 实例。
6.查找与所需类型匹配的 bean 实例,这边的返回结果 matchingBeans 的key 是 beanName,而 value 有两种情况:一种是匹配的 bean 实例,另一种是匹配的 bean 实例的类型,见代码块11详解。
7.1 从多个候选者中选出最优的那个,见代码块16详解。
protected Map<String, Object> findAutowireCandidates( String beanName, Class<?> requiredType, DependencyDescriptor descriptor) { // 1.获取给定类型的所有beanName,包括在祖先工厂中定义的beanName String[] candidateNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors( this, requiredType, true, descriptor.isEager()); Map<String, Object> result = new LinkedHashMap<String, Object>(candidateNames.length); // 2.首先从已经解析的依赖关系缓存中寻找是否存在我们想要的类型 for (Class<?> autowiringType : this.resolvableDependencies.keySet()) { // 2.1 autowiringType是否与requiredType相同,或者是requiredType的超类、超接口 if (autowiringType.isAssignableFrom(requiredType)) { // 2.2 如果requiredType匹配,则从缓存中拿到相应的自动装配值(bean实例) Object autowiringValue = this.resolvableDependencies.get(autowiringType); // 2.3 根据给定的所需类型解析给定的自动装配值 autowiringValue = AutowireUtils.resolveAutowiringValue(autowiringValue, requiredType); if (requiredType.isInstance(autowiringValue)) { // 2.4 将autowiringValue放到结果集中,此时的value为bean实例 result.put(ObjectUtils.identityToString(autowiringValue), autowiringValue); break; } } } // 3.遍历从容器中获取到的类型符合的beanName for (String candidate : candidateNames) { // isAutowireCandidate:判断是否有资格作为依赖注入的候选者 // 3.1 如果不是自引用 && candidate有资格作为依赖注入的候选者 if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, descriptor)) { // 3.2 将候选者添加到result中 addCandidateEntry(result, candidate, descriptor, requiredType); } } // 4.如果结果为空 && type不是MultipleBean(Array、Collection、Map),则使用降级匹配 if (result.isEmpty() && !indicatesMultipleBeans(requiredType)) { // Consider fallback matches if the first pass failed to find anything... // 4.1 使用降级匹配(跟正常匹配类似) DependencyDescriptor fallbackDescriptor = descriptor.forFallbackMatch(); for (String candidate : candidateNames) { if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, fallbackDescriptor)) { addCandidateEntry(result, candidate, descriptor, requiredType); } } if (result.isEmpty()) { // Consider self references as a final pass... // but in the case of a dependency collection, not the very same bean itself. // 5.如果使用降级匹配结果还是空,则考虑自引用 for (String candidate : candidateNames) { if (isSelfReference(beanName, candidate) && (!(descriptor instanceof MultiElementDescriptor) || !beanName.equals(candidate)) && isAutowireCandidate(candidate, fallbackDescriptor)) { // 5.1 如果是自引用 && (descriptor不是MultiElementDescriptor || beanName不等于候选者) // && candidate允许依赖注入,则将候选者添加到result中 addCandidateEntry(result, candidate, descriptor, requiredType); } } } } // 6.返回符合条件的候选者 return result; }
3.1 isAutowireCandidate:判断是否有资格作为依赖注入的候选者,见代码块12详解。
3.2 将候选者添加到 result 中,见代码块15详解。
@Override public boolean isAutowireCandidate(String beanName, DependencyDescriptor descriptor) throws NoSuchBeanDefinitionException { // getAutowireCandidateResolver: 返回BeanFactory的@Autowire解析器,开启注解后的解析器为:ContextAnnotationAutowireCandidateResolver // 解析beanName对应的bean是否有资格作为候选者 return isAutowireCandidate(beanName, descriptor, getAutowireCandidateResolver()); } protected boolean isAutowireCandidate(String beanName, DependencyDescriptor descriptor, AutowireCandidateResolver resolver) throws NoSuchBeanDefinitionException { // 1.解析beanName,去掉FactoryBean的修饰符“&” String beanDefinitionName = BeanFactoryUtils.transformedBeanName(beanName); if (containsBeanDefinition(beanDefinitionName)) { // 2.beanDefinitionMap缓存中存在beanDefinitionName:通过beanDefinitionName缓存拿到MergedBeanDefinition, // 将MergedBeanDefinition作为参数,解析beanName是否有资格作为候选者 return isAutowireCandidate(beanName, getMergedLocalBeanDefinition(beanDefinitionName), descriptor, resolver); } else if (containsSingleton(beanName)) { // 3.singletonObjects缓存中存在beanName:使用beanName构建RootBeanDefinition作为参数,解析beanName是否有资格作为候选者 return isAutowireCandidate(beanName, new RootBeanDefinition(getType(beanName)), descriptor, resolver); } // 4.在beanDefinitionMap缓存和singletonObjects缓存中都不存在,则在parentBeanFactory中递归解析beanName是否有资格作为候选者 BeanFactory parent = getParentBeanFactory(); if (parent instanceof DefaultListableBeanFactory) { // No bean definition found in this factory -> delegate to parent. return ((DefaultListableBeanFactory) parent).isAutowireCandidate(beanName, descriptor, resolver); } else if (parent instanceof ConfigurableListableBeanFactory) { // If no DefaultListableBeanFactory, can't pass the resolver along. return ((ConfigurableListableBeanFactory) parent).isAutowireCandidate(beanName, descriptor); } else { return true; } }
这边的 ContextAnnotationAutowireCandidateResolver 在Spring IoC:context:component-scan节点详解文中的代码块17被赋值给 BeanFacoty 的 autowireCandidateResolver 属性。
2.继续解析 beanName 是否有资格作为候选者,见代码块13详解。
protected boolean isAutowireCandidate(String beanName, RootBeanDefinition mbd, DependencyDescriptor descriptor, AutowireCandidateResolver resolver) { // 1.解析beanName,去掉FactoryBean的修饰符“&” String beanDefinitionName = BeanFactoryUtils.transformedBeanName(beanName); // 2.解析mbd的beanClass resolveBeanClass(mbd, beanDefinitionName); if (mbd.isFactoryMethodUnique) { boolean resolve; synchronized (mbd.constructorArgumentLock) { resolve = (mbd.resolvedConstructorOrFactoryMethod == null); } if (resolve) { // 3.如果缓存中已经存在解析的构造函数或工厂方法,则解析mbd中的工厂方法,并替换掉缓存中的方法 new ConstructorResolver(this).resolveFactoryMethodIfPossible(mbd); } } // 4.使用resolver解析器解析mbd是否有资格作为依赖注入的候选者 return resolver.isAutowireCandidate( new BeanDefinitionHolder(mbd, beanName, getAliases(beanDefinitionName)), descriptor); }
4.使用 resolver(ContextAnnotationAutowireCandidateResolver)解析器解析mbd 是否有资格作为依赖注入的候选者,见代码块14详解。
@Override public boolean isAutowireCandidate(BeanDefinitionHolder bdHolder, DependencyDescriptor descriptor) { // 1.调用父类方法判断此bean是否可以自动注入到其他bean boolean match = super.isAutowireCandidate(bdHolder, descriptor); if (match && descriptor != null) { // 2.@Qualifiers注解检查 match = checkQualifiers(bdHolder, descriptor.getAnnotations()); if (match) { MethodParameter methodParam = descriptor.getMethodParameter(); if (methodParam != null) { Method method = methodParam.getMethod(); if (method == null || void.class == method.getReturnType()) { match = checkQualifiers(bdHolder, methodParam.getMethodAnnotations()); } } } } return match; } // GenericTypeAwareAutowireCandidateResolver.java @Override public boolean isAutowireCandidate(BeanDefinitionHolder bdHolder, DependencyDescriptor descriptor) { if (!super.isAutowireCandidate(bdHolder, descriptor)) { // If explicitly false, do not proceed with any other checks... // 1.如果父类返回false,则直接返回false return false; } // 2.descriptor为空 || bdHolder的类型与descriptor的类型匹配,则返回true return (descriptor == null || checkGenericTypeMatch(bdHolder, descriptor)); } // SimpleAutowireCandidateResolver.java @Override public boolean isAutowireCandidate(BeanDefinitionHolder bdHolder, DependencyDescriptor descriptor) { // 获取此bean是否可以自动注入到其他bean(autowireCandidate属性),默认为true,一般不修改,因此这边返回true return bdHolder.getBeanDefinition().isAutowireCandidate(); }
ContextAnnotationAutowireCandidateResolver 继承了 QualifierAnnotationAutowireCandidateResolver,所以这边最开始会走到 QualifierAnnotationAutowireCandidateResolver 中的方法。
private void addCandidateEntry(Map<String, Object> candidates, String candidateName, DependencyDescriptor descriptor, Class<?> requiredType) { // 1.如果descriptor为MultiElementDescriptor类型 || candidateName已经在singletonObjects缓存中存在 if (descriptor instanceof MultiElementDescriptor || containsSingleton(candidateName)) { // 2.1 resolveCandidate: 通过candidateName获取对应的bean实例 // 2.2 将beanName -> bean实例 的映射添加到candidates(此时的value为bean实例) candidates.put(candidateName, descriptor.resolveCandidate(candidateName, requiredType, this)); } else { // 3.将beanName -> bean实例的类型 的映射添加到candidates(此时的value为bean实例的类型) candidates.put(candidateName, getType(candidateName)); } }
当被依赖注入的属性是 MultipleBean(Array、Collection、Map)类型,生成的依赖描述类型是 MultiElementDescriptor,因此所有的候选者均是合格的,所以会当场实例化他们(2.1)。而如果属性的类型是非 MultipleBean,那么可能是从多个候选者中挑一个最合适的,因此此时实例化他们就不合适了,最终会把最合适的那个实例化,如果没有合格的则不应该实例化。
代码块16:determineAutowireCandidate
protected String determineAutowireCandidate(Map<String, Object> candidates, DependencyDescriptor descriptor) { Class<?> requiredType = descriptor.getDependencyType(); // 1.根据@Primary注解来选择最优解 String primaryCandidate = determinePrimaryCandidate(candidates, requiredType); if (primaryCandidate != null) { return primaryCandidate; } // 2.根据@Priority注解来选择最优解 String priorityCandidate = determineHighestPriorityCandidate(candidates, requiredType); if (priorityCandidate != null) { return priorityCandidate; } // Fallback // 3.如果通过以上两步都不能选择出最优解,则使用最基本的策略 for (Map.Entry<String, Object> entry : candidates.entrySet()) { String candidateName = entry.getKey(); Object beanInstance = entry.getValue(); // 3.1 containsValue:首先如果这个beanInstance已经由Spring注册过依赖关系,则直接使用该beanInstance作为最优解, // 3.2 matchesBeanName:如果没有注册过此beanInstance的依赖关系,则根据参数名称来匹配, // 如果参数名称和某个候选者的beanName或别名一致,那么直接将此bean作为最优解 if ((beanInstance != null && this.resolvableDependencies.containsValue(beanInstance)) || matchesBeanName(candidateName, descriptor.getDependencyName())) { return candidateName; } } // 4.没有找到匹配的候选者,则返回null return null; } protected boolean matchesBeanName(String beanName, String candidateName) { // candidateName与beanName相等 || beanName有别名与candidateName相等,则返回true return (candidateName != null && (candidateName.equals(beanName) || ObjectUtils.containsElement(getAliases(beanName), candidateName))); }
1.根据 @Primary 注解来选择最优解,见代码块17详解。
2.根据 @Priority 注解来选择最优解,见代码块18详解。
代码块17:determinePrimaryCandidate
protected String determinePrimaryCandidate(Map<String, Object> candidates, Class<?> requiredType) { String primaryBeanName = null; // 1.遍历所有候选者 for (Map.Entry<String, Object> entry : candidates.entrySet()) { String candidateBeanName = entry.getKey(); Object beanInstance = entry.getValue(); // 2.判断候选者bean是否使用了@Primary注解:如果candidateBeanName在当前BeanFactory中存在BeanDefinition, // 则判断当前BeanFactory中的BeanDefinition是否使用@Primary修饰;否则,在parentBeanFactory中判断 if (isPrimary(candidateBeanName, beanInstance)) { if (primaryBeanName != null) { // 3.走到这边primaryBeanName不为null,代表标识了@Primary的候选者不止一个,则判断BeanName是否存在于当前BeanFactory // candidateLocal:candidateBeanName是否在当前BeanFactory的beanDefinitionMap缓存中 boolean candidateLocal = containsBeanDefinition(candidateBeanName); // primaryLocal:primaryBeanName是否在当前BeanFactory的beanDefinitionMap缓存中 boolean primaryLocal = containsBeanDefinition(primaryBeanName); if (candidateLocal && primaryLocal) { // 3.1 如果当前BeanFactory中同一个类型的多个Bean,不止一个Bean使用@Primary注解,则抛出异常 throw new NoUniqueBeanDefinitionException(requiredType, candidates.size(), "more than one 'primary' bean found among candidates: " + candidates.keySet()); } else if (candidateLocal) { // 3.2 candidateLocal为true,primaryLocal为false,则代表primaryBeanName是parentBeanFactory中的Bean, // candidateBeanName是当前BeanFactory中的Bean,当存在两个都使用@Primary注解的Bean,优先使用当前BeanFactory中的 primaryBeanName = candidateBeanName; } // 3.3 candidateLocal为false,primaryLocal为true,则代表primaryBeanName是当前BeanFactory中的Bean, // candidateBeanName是parentBeanFactory中的Bean,因此无需修改primaryBeanName的值 } else { // 4.primaryBeanName还为空,代表是第一个符合的候选者,直接将primaryBeanName赋值为candidateBeanName primaryBeanName = candidateBeanName; } } } // 5.返回唯一的使用@Primary注解的Bean的beanName(如果都没使用@Primary注解则返回null) return primaryBeanName; }
代码块18:determineHighestPriorityCandidate
protected String determineHighestPriorityCandidate(Map<String, Object> candidates, Class<?> requiredType) { // 用来保存最高优先级的beanName String highestPriorityBeanName = null; // 用来保存最高优先级的优先级值 Integer highestPriority = null; // 1.遍历所有候选者 for (Map.Entry<String, Object> entry : candidates.entrySet()) { String candidateBeanName = entry.getKey(); Object beanInstance = entry.getValue(); // 2.拿到beanInstance的优先级 Integer candidatePriority = getPriority(beanInstance); if (candidatePriority != null) { if (highestPriorityBeanName != null) { // 3.如果之前已经有候选者有优先级,则进行选择 if (candidatePriority.equals(highestPriority)) { // 3.1 如果存在两个优先级相同的Bean,则抛出异常 throw new NoUniqueBeanDefinitionException(requiredType, candidates.size(), "Multiple beans found with the same priority ('" + highestPriority + "') among candidates: " + candidates.keySet()); } else if (candidatePriority < highestPriority) { // 3.2 使用优先级值较小的Bean作为最优解(值越低,优先级越高) highestPriorityBeanName = candidateBeanName; highestPriority = candidatePriority; } } else { // 4.第一次有候选者有优先级 highestPriorityBeanName = candidateBeanName; highestPriority = candidatePriority; } } } // 5.返回优先级最高的bean的beanName return highestPriorityBeanName; }
public void storeCache(RootBeanDefinition mbd, Object constructorOrFactoryMethod) { synchronized (mbd.constructorArgumentLock) { // 将构造函数或工厂方法放到resolvedConstructorOrFactoryMethod缓存 mbd.resolvedConstructorOrFactoryMethod = constructorOrFactoryMethod; // constructorArgumentsResolved标记为已解析 mbd.constructorArgumentsResolved = true; if (this.resolveNecessary) { // 如果参数需要解析,则将preparedArguments放到preparedConstructorArguments缓存 mbd.preparedConstructorArguments = this.preparedArguments; } else { // 如果参数不需要解析,则将arguments放到resolvedConstructorArguments缓存 mbd.resolvedConstructorArguments = this.arguments; } } }
本文介绍了创建 bean 实例中的一个重要内容:创建一个新的 bean 实例。创建 bean 实例中剩下的:填充属性、bean 实例初始化等内容,将在下篇文章介绍。