前言 编写代码中遇到一个问题,下面的代码一有时不会生效,必须通过代码二的方式,通过set方法注入DataSource然后再隐式转换赋值,所以稍微研究一下Autowired注解
1 2 3 4 5 6 7 8 9 @Autowired private DynamicRoutingDataSource dataSource;@Autowired public void setDataSource (DataSource dataSource) { this .dataSource = (DynamicRoutingDataSource) dataSource; }
DynamicRoutingDataSource对象实例化的方法
1 2 3 4 5 6 7 8 9 10 11 @Bean @ConditionalOnMissingBean public DataSource dataSource (DynamicDataSourceProvider dynamicDataSourceProvider) { DynamicRoutingDataSource dataSource = new DynamicRoutingDataSource (); dataSource.setPrimary(this .properties.getPrimary()); dataSource.setStrategy(this .properties.getStrategy()); dataSource.setProvider(dynamicDataSourceProvider); dataSource.setP6spy(this .properties.getP6spy()); dataSource.setStrict(this .properties.getStrict()); return dataSource; }
涉及相关类 InstantiationAwareBeanPostProcessor InstantiationAwareBeanPostProcessor的作用是在属性赋值时,进行一些额外的操作,它是Autowired注解发挥作用最根本的类,Spring创建Bean的过程中,在执行populateBean为对象变量赋值时,大部分地方都在调用InstantiationAwareBeanPostProcessor的方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor { @Nullable default Object postProcessBeforeInstantiation (Class<?> beanClass, String beanName) throws BeansException { return null ; } default boolean postProcessAfterInstantiation (Object bean, String beanName) throws BeansException { return true ; } @Nullable default PropertyValues postProcessProperties (PropertyValues pvs, Object bean, String beanName) throws BeansException { return null ; } @Deprecated @Nullable default PropertyValues postProcessPropertyValues (PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException { return pvs; } }
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 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 protected void populateBean (String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) { if (bw == null ) { if (mbd.hasPropertyValues()) { throw new BeanCreationException (mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance" ); } } else { if (!mbd.isSynthetic() && this .hasInstantiationAwareBeanPostProcessors()) { Iterator var4 = this .getBeanPostProcessorCache().instantiationAware.iterator(); while (var4.hasNext()) { InstantiationAwareBeanPostProcessor bp = (InstantiationAwareBeanPostProcessor)var4.next(); if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) { return ; } } } PropertyValues pvs = mbd.hasPropertyValues() ? mbd.getPropertyValues() : null ; int resolvedAutowireMode = mbd.getResolvedAutowireMode(); if (resolvedAutowireMode == 1 || resolvedAutowireMode == 2 ) { MutablePropertyValues newPvs = new MutablePropertyValues ((PropertyValues)pvs); if (resolvedAutowireMode == 1 ) { this .autowireByName(beanName, mbd, bw, newPvs); } if (resolvedAutowireMode == 2 ) { this .autowireByType(beanName, mbd, bw, newPvs); } pvs = newPvs; } boolean hasInstAwareBpps = this .hasInstantiationAwareBeanPostProcessors(); boolean needsDepCheck = mbd.getDependencyCheck() != 0 ; PropertyDescriptor[] filteredPds = null ; if (hasInstAwareBpps) { if (pvs == null ) { pvs = mbd.getPropertyValues(); } PropertyValues pvsToUse; for (Iterator var9 = this .getBeanPostProcessorCache().instantiationAware.iterator(); var9.hasNext(); pvs = pvsToUse) { InstantiationAwareBeanPostProcessor bp = (InstantiationAwareBeanPostProcessor)var9.next(); pvsToUse = bp.postProcessProperties((PropertyValues)pvs, bw.getWrappedInstance(), beanName); if (pvsToUse == null ) { if (filteredPds == null ) { filteredPds = this .filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching); } pvsToUse = bp.postProcessPropertyValues((PropertyValues)pvs, filteredPds, bw.getWrappedInstance(), beanName); if (pvsToUse == null ) { return ; } } } } if (needsDepCheck) { if (filteredPds == null ) { filteredPds = this .filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching); } this .checkDependencies(beanName, mbd, filteredPds, (PropertyValues)pvs); } if (pvs != null ) { this .applyPropertyValues(beanName, mbd, bw, (PropertyValues)pvs); } } }
从populateBean代码可以看出,InstantiationAwareBeanPostProcessor对于populateBean方法相当重要。
关于popluate中调用autowireByName和autowireByType,这两个方法是根据相应的策略,为类中的set方法进行装配,如果是ByName,则根据set方法“set”后面的名称装配,如果是ByType,则根据方法内的参数类型进行装配,在这里还没有为变量赋值,只是先确定赋哪个值,可以通过xml配置或者@Bean注解的方式配置这两者,默认不启用
//以下情况将调用autowireByName装配 //<bean>设置autowire属性
<bean id="exampleBean" class="com.example.ExampleBean" autowire="byName">***</bean>
或
//@Bean注解使用autowire属性
@Bean(name = "exampleBean", autowire = Autowire.BY_NAME)
## AutowiredAnnotationBeanPostProcessor
AutowiredAnnotationBeanPostProcessor实现了InstantiationAwareBeanPostProcessor,是实现Autowired注解逻辑的直接类,它实现的postProcessProperties方法会在类给属性赋值时,检查类对象使用到Autowired注解的变量或者方法,如果有,则尝试为对象变量赋值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 public PropertyValues postProcessProperties (PropertyValues pvs, Object bean, String beanName) { InjectionMetadata metadata = this .findAutowiringMetadata(beanName, bean.getClass(), pvs); try { metadata.inject(bean, beanName, pvs); return pvs; } catch (BeanCreationException var6) { throw var6; } catch (Throwable var7) { throw new BeanCreationException (beanName, "Injection of autowired dependencies failed" , var7); } }
这个类主要用于存储和管理与注解相关的元数据,这些元数据描述了如何以及在哪里应用自动注入。上述介绍的postProcessProperties方法中就用到了它。具体来说, InjectionMetadata 会收集以下信息:
注解的类型和属性。
需要执行注入的目标成员(如字段或方法)。
任何可能影响注入行为的特定配置(例如,是否需要强制要求依赖存在)。
AutowiredFieldElement AutowiredFieldElement位于InjectionMetadata内部,它代表了注入点的一个基本元素,可以是一个需要进行依赖注入的字段、方法或是构造函数。这个类为处理各种类型的注入点提供了一个统一的基础抽象,封装了执行注入操作所需的基本逻辑和信息。AutowiredFieldElement有一个inject方法,它的子类通过实现这个方法完成不同的注入功能
AutowiredAnnotationBeanPostProcessor实现两个AutowiredFieldElement
AutowiredFieldElement:负责处理 需要进行依赖注入的字段,例如直接在字段上使用@Autowired注解
AutowiredMethodElement:负责处理负责处理需要进行依赖注入的方法,例如直接在set方法上使用@Autowired注解
DefaultListableBeanFactory DefaultListableBeanFactory 提供了Bean定义的注册、Bean的创建、配置、管理和依赖注入等功能。是Spring框架中一个非常核心的类,它是Spring IoC容器的基础实现之一,负责管理和维护bean的定义( BeanDefinition )以及bean的实例化、配置和组装工作。这个类属于Spring的 beans 包下,是构建Spring应用上下文(ApplicationContext)的基石
doResolveDependency doResolveDependency方法,它是Spring框架中bean依赖解析过程的一个核心步骤。这个方法主要用于解决和创建应用程序在运行时需要的bean之间的依赖关系。它是Spring IoC容器如何管理bean间复杂依赖关系背后的关键逻辑实现之一。根据步骤,它会解析依赖描述、查找候选bean、处理泛型依赖、创建或获取bean实例、处理特殊依赖类型、类型转换、处理可选依赖
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 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 public Object doResolveDependency (DependencyDescriptor descriptor, @Nullable String beanName, @Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException { InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor); Object var7; try { Object shortcut = descriptor.resolveShortcut(this ); if (shortcut == null ) { Class<?> type = descriptor.getDependencyType(); Object value = this .getAutowireCandidateResolver().getSuggestedValue(descriptor); Object var23; if (value != null ) { if (value instanceof String) { String strVal = this .resolveEmbeddedValue((String)value); BeanDefinition bd = beanName != null && this .containsBean(beanName) ? this .getMergedBeanDefinition(beanName) : null ; value = this .evaluateBeanDefinitionString(strVal, bd); } TypeConverter converter = typeConverter != null ? typeConverter : this .getTypeConverter(); try { var23 = converter.convertIfNecessary(value, type, descriptor.getTypeDescriptor()); return var23; } catch (UnsupportedOperationException var18) { Object var25 = descriptor.getField() != null ? converter.convertIfNecessary(value, type, descriptor.getField()) : converter.convertIfNecessary(value, type, descriptor.getMethodParameter()); return var25; } } Object multipleBeans = this .resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter); if (multipleBeans != null ) { var23 = multipleBeans; return var23; } Map<String, Object> matchingBeans = this .findAutowireCandidates(beanName, type, descriptor); String autowiredBeanName; if (matchingBeans.isEmpty()) { if (this .isRequired(descriptor)) { this .raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor); } autowiredBeanName = null ; return autowiredBeanName; } Object instanceCandidate; Object result; if (matchingBeans.size() > 1 ) { autowiredBeanName = this .determineAutowireCandidate(matchingBeans, descriptor); if (autowiredBeanName == null ) { if (!this .isRequired(descriptor) && this .indicatesMultipleBeans(type)) { result = null ; return result; } result = descriptor.resolveNotUnique(descriptor.getResolvableType(), matchingBeans); return result; } instanceCandidate = matchingBeans.get(autowiredBeanName); } else { Map.Entry<String, Object> entry = (Map.Entry)matchingBeans.entrySet().iterator().next(); autowiredBeanName = (String)entry.getKey(); instanceCandidate = entry.getValue(); } if (autowiredBeanNames != null ) { autowiredBeanNames.add(autowiredBeanName); } if (instanceCandidate instanceof Class) { instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this ); } result = instanceCandidate; if (instanceCandidate instanceof NullBean) { if (this .isRequired(descriptor)) { this .raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor); } result = null ; } if (!ClassUtils.isAssignableValue(type, result)) { throw new BeanNotOfRequiredTypeException (autowiredBeanName, type, instanceCandidate.getClass()); } Object var14 = result; return var14; } var7 = shortcut; } finally { ConstructorResolver.setCurrentInjectionPoint(previousInjectionPoint); } return var7; }
这个方法比较重要的一步就是查找候选者,即上述代码中的
Map<String, Object> matchingBeans = this.findAutowireCandidates(beanName, type, descriptor);
这一步是查询候选者,返回的可能是生成好的Bean实例,也有可能是Bean的Class对象,
findAutowireCandidates findAutowireCandidates 方法是Spring框架IoC(控制反转)容器中的一个重要组成部分。该方法负责在容器中寻找可以自动装配的bean候选者,这主要发生在依赖注入的过程中。它不仅会寻找bean候选者,还会尝试获取实例,它会尝试先获取候选者的名称,然后判断是否存在候选者的实例,如果存在,则返回候选者实例,如果不存在,则返回候选者的类型
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 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 protected Map<String, Object> findAutowireCandidates (@Nullable String beanName, Class<?> requiredType, DependencyDescriptor descriptor) { String[] candidateNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(this , requiredType, true , descriptor.isEager()); Map<String, Object> result = CollectionUtils.newLinkedHashMap(candidateNames.length); Iterator var6 = this .resolvableDependencies.entrySet().iterator(); while (var6.hasNext()) { Map.Entry<Class<?>, Object> classObjectEntry = (Map.Entry)var6.next(); Class<?> autowiringType = (Class)classObjectEntry.getKey(); if (autowiringType.isAssignableFrom(requiredType)) { Object autowiringValue = classObjectEntry.getValue(); autowiringValue = AutowireUtils.resolveAutowiringValue(autowiringValue, requiredType); if (requiredType.isInstance(autowiringValue)) { result.put(ObjectUtils.identityToString(autowiringValue), autowiringValue); break ; } } } String[] var12 = candidateNames; int var14 = candidateNames.length; for (int var16 = 0 ; var16 < var14; ++var16) { String candidate = var12[var16]; if (!this .isSelfReference(beanName, candidate) && this .isAutowireCandidate(candidate, descriptor)) { this .addCandidateEntry(result, candidate, descriptor, requiredType); } } if (result.isEmpty()) { boolean multiple = this .indicatesMultipleBeans(requiredType); DependencyDescriptor fallbackDescriptor = descriptor.forFallbackMatch(); String[] var17 = candidateNames; int var19 = candidateNames.length; int var10; String candidate; for (var10 = 0 ; var10 < var19; ++var10) { candidate = var17[var10]; if (!this .isSelfReference(beanName, candidate) && this .isAutowireCandidate(candidate, fallbackDescriptor) && (!multiple || this .getAutowireCandidateResolver().hasQualifier(descriptor))) { this .addCandidateEntry(result, candidate, descriptor, requiredType); } } if (result.isEmpty() && !multiple) { var17 = candidateNames; var19 = candidateNames.length; for (var10 = 0 ; var10 < var19; ++var10) { candidate = var17[var10]; if (this .isSelfReference(beanName, candidate) && (!(descriptor instanceof MultiElementDescriptor) || !beanName.equals(candidate)) && this .isAutowireCandidate(candidate, fallbackDescriptor)) { this .addCandidateEntry(result, candidate, descriptor, requiredType); } } } } return result; }
这个方法当中
BeanFactoryUtils.beanNamesForTypeIncludingAncestors获取候选者名称
addCandidateEntry会尝试获取候选者实例或者类型
findAutowireCandidates方法后面涉及到一个比较重要的方法就是doGetBeanNamesForType,是实现获取候选者名称的关键之一
doGetBeanNamesForType doGetBeanNamesForType 是Spring IoC容器核心功能的一部分。这个方法主要用于根据给定的类型查找并返回所有匹配的bean名称列表。它是Spring在内部用于处理按类型查找Bean的请求的关键方法。它主要是通过遍历beanDefinitionNames(Spring Boot中所有Bean定义名称的集合,一般为类名或者类全限定名),然后判断是否和需要解析的Bean匹配,然后返回所有匹配的Bean名称
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 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 private String[] doGetBeanNamesForType(ResolvableType type, boolean includeNonSingletons, boolean allowEagerInit) { List<String> result = new ArrayList (); Iterator var5 = this .beanDefinitionNames.iterator(); while (true ) { String beanName; do { if (!var5.hasNext()) { var5 = this .manualSingletonNames.iterator(); while (var5.hasNext()) { beanName = (String)var5.next(); try { if (this .isFactoryBean(beanName)) { if ((includeNonSingletons || this .isSingleton(beanName)) && this .isTypeMatch(beanName, type)) { result.add(beanName); continue ; } beanName = "&" + beanName; } if (this .isTypeMatch(beanName, type)) { result.add(beanName); } } catch (NoSuchBeanDefinitionException var13) { this .logger.trace(LogMessage.format("Failed to check manually registered singleton with name '%s'" , beanName), var13); } } return StringUtils.toStringArray(result); } beanName = (String)var5.next(); } while (this .isAlias(beanName)); try { RootBeanDefinition mbd = this .getMergedLocalBeanDefinition(beanName); if (!mbd.isAbstract() && (allowEagerInit || (mbd.hasBeanClass() || !mbd.isLazyInit() || this .isAllowEagerClassLoading()) && !this .requiresEagerInitForType(mbd.getFactoryBeanName()))) { boolean isFactoryBean = this .isFactoryBean(beanName, mbd); BeanDefinitionHolder dbd = mbd.getDecoratedDefinition(); boolean matchFound = false ; boolean allowFactoryBeanInit = allowEagerInit || this .containsSingleton(beanName); boolean isNonLazyDecorated = dbd != null && !mbd.isLazyInit(); if (!isFactoryBean) { if (includeNonSingletons || this .isSingleton(beanName, mbd, dbd)) { matchFound = this .isTypeMatch(beanName, type, allowFactoryBeanInit); } } else { if (includeNonSingletons || isNonLazyDecorated || allowFactoryBeanInit && this .isSingleton(beanName, mbd, dbd)) { matchFound = this .isTypeMatch(beanName, type, allowFactoryBeanInit); } if (!matchFound) { beanName = "&" + beanName; if (includeNonSingletons || this .isSingleton(beanName, mbd, dbd)) { matchFound = this .isTypeMatch(beanName, type, allowFactoryBeanInit); } } } if (matchFound) { result.add(beanName); } } } catch (BeanDefinitionStoreException | CannotLoadBeanClassException var14) { if (allowEagerInit) { throw var14; } LogMessage message = var14 instanceof CannotLoadBeanClassException ? LogMessage.format("Ignoring bean class loading failure for bean '%s'" , beanName) : LogMessage.format("Ignoring unresolvable metadata in bean definition '%s'" , beanName); this .logger.trace(message, var14); this .onSuppressedException(var14); } catch (NoSuchBeanDefinitionException var15) { } } }
这个方法当中比较关键的就是通过isTypeMatch筛选符合条件的Bean的名称
isTypeMatch isTypeMatch 是Spring IoC容器内部用于检查和验证Bean类型是否匹配的核心方法之一。这个方法主要用于在实例化或注入Bean之前,确定一个已经注册的Bean(通过名字指定)是否与期望的类型相匹配。开头讲到通过方式一注入有时候行有时候不行,就是在这里找到了原因
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 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 protected boolean isTypeMatch (String name, ResolvableType typeToMatch, boolean allowFactoryBeanInit) throws NoSuchBeanDefinitionException { String beanName = this .transformedBeanName(name); boolean isFactoryDereference = BeanFactoryUtils.isFactoryDereference(name); Object beanInstance = this .getSingleton(beanName, false ); if (beanInstance != null && beanInstance.getClass() != NullBean.class) { if (beanInstance instanceof FactoryBean) { if (isFactoryDereference) { return typeToMatch.isInstance(beanInstance); } else { Class<?> type = this .getTypeForFactoryBean((FactoryBean)beanInstance); return type != null && typeToMatch.isAssignableFrom(type); } } else { if (!isFactoryDereference) { if (typeToMatch.isInstance(beanInstance)) { return true ; } if (typeToMatch.hasGenerics() && this .containsBeanDefinition(beanName)) { RootBeanDefinition mbd = this .getMergedLocalBeanDefinition(beanName); Class<?> targetType = mbd.getTargetType(); if (targetType != null && targetType != ClassUtils.getUserClass(beanInstance)) { Class<?> classToMatch = typeToMatch.resolve(); if (classToMatch != null && !classToMatch.isInstance(beanInstance)) { return false ; } if (typeToMatch.isAssignableFrom(targetType)) { return true ; } } ResolvableType resolvableType = mbd.targetType; if (resolvableType == null ) { resolvableType = mbd.factoryMethodReturnType; } return resolvableType != null && typeToMatch.isAssignableFrom(resolvableType); } } return false ; } } else if (this .containsSingleton(beanName) && !this .containsBeanDefinition(beanName)) { return false ; } else { BeanFactory parentBeanFactory = this .getParentBeanFactory(); if (parentBeanFactory != null && !this .containsBeanDefinition(beanName)) { return parentBeanFactory.isTypeMatch(this .originalBeanName(name), typeToMatch); } else { RootBeanDefinition mbd = this .getMergedLocalBeanDefinition(beanName); BeanDefinitionHolder dbd = mbd.getDecoratedDefinition(); Class<?> classToMatch = typeToMatch.resolve(); if (classToMatch == null ) { classToMatch = FactoryBean.class; } Class<?>[] typesToMatch = FactoryBean.class == classToMatch ? new Class []{classToMatch} : new Class []{FactoryBean.class, classToMatch}; Class<?> predictedType = null ; if (!isFactoryDereference && dbd != null && this .isFactoryBean(beanName, mbd) && (!mbd.isLazyInit() || allowFactoryBeanInit)) { RootBeanDefinition tbd = this .getMergedBeanDefinition(dbd.getBeanName(), dbd.getBeanDefinition(), mbd); Class<?> targetType = this .predictBeanType(dbd.getBeanName(), tbd, typesToMatch); if (targetType != null && !FactoryBean.class.isAssignableFrom(targetType)) { predictedType = targetType; } } if (predictedType == null ) { predictedType = this .predictBeanType(beanName, mbd, typesToMatch); if (predictedType == null ) { return false ; } } ResolvableType beanType = null ; if (FactoryBean.class.isAssignableFrom(predictedType)) { if (beanInstance == null && !isFactoryDereference) { beanType = this .getTypeForFactoryBean(beanName, mbd, allowFactoryBeanInit); predictedType = beanType.resolve(); if (predictedType == null ) { return false ; } } } else if (isFactoryDereference) { predictedType = this .predictBeanType(beanName, mbd, FactoryBean.class); if (predictedType == null || !FactoryBean.class.isAssignableFrom(predictedType)) { return false ; } } if (beanType == null ) { ResolvableType definedType = mbd.targetType; if (definedType == null ) { definedType = mbd.factoryMethodReturnType; } if (definedType != null && definedType.resolve() == predictedType) { beanType = definedType; } } return beanType != null ? typeToMatch.isAssignableFrom(beanType) : typeToMatch.isAssignableFrom(predictedType); } } }
直接用前言中的例子放到这个方法里面分析一下,方法开始会尝试根据待匹配的BeanName获取Bean实例,如果获取成功(这里指的获取成功,代表这之前,待匹配的BeanName已经实例化完成了),则判断待匹配的Bean实例是否是需要注入的对象的类或者子类,如果获取待匹配的BeanName的实例失败,则往后执行,普通的Bean最后都会通过判断待匹配的BeanName的Bean定义中的类是否是需要注入的对象的类或者子类。
这里我们假设DynamicRoutingDataSource已经实例化完成了,那么待匹配的Bean实例就是DynamicRoutingDataSource,而我们需要注入的也是DynamicRoutingDataSource类,那么这里就ok。这里的情况是因为引入JdbcTemplate之后,JdbcTemplate会引入DataSource,导致DynamicRoutingDataSource提前实例化了
如果这里DynamicRoutingDataSource还没有实例化完成,通过前言中DynamicRoutingDataSource实例化的方法可知,DynamicRoutingDataSource的Bean定义中的类是DataSource,而DataSource不是DynamicRoutingDataSource,更不是它的子类,很明显就无法匹配,最后也无法注入
而前言中的方式二可以成功是因为,哪怕DynamicRoutingDataSource还没有实例化完成,但是我们需要注入的类是DataSource,和DynamicRoutingDataSource的Bean定义中的DataSource类是一样的,所以可以注入成功
总结 出现这种情况,是因为,需要注入的对象和候选者对象比较的时候除了问题,候选者Bean是否已经实例化会影响比较的逻辑,这里又涉及到Bean实例化的时机,像本文中的例子,JdbcTemplate会先加载DataSource。
Spring Boot会先将程序中需要注册的类先放到一个定义集合,然后ApplicationContext就会循环定义集合创建Bean实例,在创建的过程中,遇到需要注入的情况,BeanFactory会直接创建需要注入的实例