您现在的位置是:首页 >其他 >Spring 依赖注入源码网站首页其他
Spring 依赖注入源码
依赖注入
具体代码是在AbstractAutowireCapableBeanFactory
类的populateBean()
方法,此方法中主要做的事情如下:
- 实例化之后,调用
InstantiationAwareBeanPostProcessor
接口的postProcessAfterInstantiation
方法 - Spring早期通过BY_NAME或BY_TYPE两种方式,并利用set方法进行依赖注入
- 通过
InstantiationAwareBeanPostProcessor
接口的postProcessProperties()
方法进行依赖注入,典型的代表就是@Autowired
等注解的处理 - 将BeanDefinition中的PropertyValues覆盖
@Autowired
等注解的值
原始依赖注入方式
首先分析Spring早期的依赖注入
@Bean(autowire = Autowire.BY_NAME)
public UserService userService(){
return new UserService();
}
接下来就会遍历UserService中所有的set方法进行依赖注入。
对应的Spring源码是
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
int resolvedAutowireMode = mbd.getResolvedAutowireMode();
// 必须是BY_NAME或BY_TYPE
if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
// MutablePropertyValues是PropertyValues具体的实现类
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
// 这里会根据我们的配置来分别调用不同的方法
if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}
接下来看autowireByName()
方法,主要过程就是先根据set方法找出所有的属性名,然后在遍历属性名集合,去单例池中找,再赋值给pvs变量
protected void autowireByName(
String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
// 当前Bean中能进行自动注入的属性名,是根据setXXX()方法生成是属性名
String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
// 遍历每个属性名,并去获取Bean对象,并设置到pvs中
for (String propertyName : propertyNames) {
// 要进行依赖注入的属性在当前容器中是否存在
if (containsBean(propertyName)) {
// 从容器中取出来,再存入pvs中
Object bean = getBean(propertyName);
pvs.add(propertyName, bean);
// 记录一下propertyName对应的Bean被beanName给依赖了
registerDependentBean(propertyName, beanName);
if (logger.isTraceEnabled()) {
logger.trace("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");
}
}
}
}
而autowireByType()
方法其实也类似,首先得到属性名集合,再遍历集合,然后得到方法形参的类型,根据resolveDependency()
找到bean对象,再存入pvs
注解方式
我们常用的方式是利用@Autowired等注解的方式实现依赖注入的,在Spring源码AbstractAutowireCapableBeanFactory
类的populateBean()
方法中对应的实现其实就是利用InstantiationAwareBeanPostProcessor
接口的postProcessProperties()
方法实现的
for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
// @Autowired注解 这里会调用AutowiredAnnotationBeanPostProcessor的postProcessProperties()方法,会直接给对象中的属性赋值
// AutowiredAnnotationBeanPostProcessor内部并不会处理pvs,直接返回了
PropertyValues pvsToUse = bp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
if (filteredPds == null) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
pvsToUse = bp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
return;
}
}
pvs = pvsToUse;
}
@Autowired
和@Value
注解是通过AutowiredAnnotationBeanPostProcessor
类处理的
@Resource
注解是通过CommonAnnotationBeanPostProcessor
类处理的
实现看AutowiredAnnotationBeanPostProcessor
类的定义,它实现了初始化后置处理器以及BeanDefinition后置处理器两个接口,所以该类就会有下面两个方法
InstantiationAwareBeanPostProcessor
接口的postProcessProperties()
方法
MergedBeanDefinitionPostProcessor
接口的postProcessMergedBeanDefinition()
方法
public class AutowiredAnnotationBeanPostProcessor implements SmartInstantiationAwareBeanPostProcessor,
MergedBeanDefinitionPostProcessor, PriorityOrdered, BeanFactoryAware {
...
}
根据我们对Bean生命周期的了解可以知道,postProcessMergedBeanDefinition()
方法先执行,postProcessProperties()
方法后执行
寻找注入点
我们可以先想一想如果要自己实现依赖注入应该要怎么做?首先就是找出类里面所有加了@Autowired注解的属性和Set方法,这个也称为注入点,然后在为这些注入点赋值。接下来看具体的实现,首先的BeanDefinition的后置处理器方法
@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
// 根据类的class对象找到所有的注入点
InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null);
metadata.checkConfigMembers(beanDefinition);
}
先看findAutowiringMetadata()
方法逻辑
private InjectionMetadata findAutowiringMetadata(String beanName, Class<?> clazz, @Nullable PropertyValues pvs) {
// cacheKey其实就beanName
String cacheKey = (StringUtils.hasLength(beanName) ? beanName : clazz.getName());
// 该类的所有注入点会缓存到injectionMetadataCache中
InjectionMetadata metadata = this.injectionMetadataCache.get(cacheKey);
if (InjectionMetadata.needsRefresh(metadata, clazz)) {
synchronized (this.injectionMetadataCache) {
metadata = this.injectionMetadataCache.get(cacheKey);
if (InjectionMetadata.needsRefresh(metadata, clazz)) {
if (metadata != null) {
metadata.clear(pvs);
}
// 解析注入点并缓存
metadata = buildAutowiringMetadata(clazz);
this.injectionMetadataCache.put(cacheKey, metadata);
}
}
}
return metadata;
}
核心方法就是buildAutowiringMetadata()
根据class找到所有的注入点
private InjectionMetadata buildAutowiringMetadata(final Class<?> clazz) {
// 如果一个Bean的类型是java.*包下的类,比如String,那么则根本不需要为该类进行依赖注入
if (!AnnotationUtils.isCandidateClass(clazz, this.autowiredAnnotationTypes)) {
return InjectionMetadata.EMPTY;
}
List<InjectionMetadata.InjectedElement> elements = new ArrayList<>();
Class<?> targetClass = clazz;
do {
final List<InjectionMetadata.InjectedElement> currElements = new ArrayList<>();
// 遍历targetClass中的所有Field,每个field都去执行第二个参数的lambda表达式
ReflectionUtils.doWithLocalFields(targetClass, field -> {
// field上是否存在@Autowired、@Value、@Inject中的其中一个
MergedAnnotation<?> ann = findAutowiredAnnotation(field);
if (ann != null) {
// static filed不是注入点,不会进行自动注入
if (Modifier.isStatic(field.getModifiers())) {
if (logger.isInfoEnabled()) {
logger.info("Autowired annotation is not supported on static fields: " + field);
}
return;
}
// 解析@Autowired注解中的required属性的值,判断这个字段是否是必须要进行注入
boolean required = determineRequiredStatus(ann);
// 再构造一个 AutowiredFieldElement 对象作为注入点对象存入集合中
currElements.add(new AutowiredFieldElement(field, required));
}
});
// 遍历targetClass中的所有Method,每个Method对象都去执行后面的lambda表达式
ReflectionUtils.doWithLocalMethods(targetClass, method -> {
// 判断当前Method是否是桥接方法,如果是找到原方法
Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
if (!BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) {
return;
}
// method上是否存在@Autowired、@Value、@Inject中的其中一个
MergedAnnotation<?> ann = findAutowiredAnnotation(bridgedMethod);
if (ann != null && method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
// static method不是注入点,不会进行自动注入
if (Modifier.isStatic(method.getModifiers())) {
if (logger.isInfoEnabled()) {
logger.info("Autowired annotation is not supported on static methods: " + method);
}
return;
}
// set方法最好有入参
if (method.getParameterCount() == 0) {
if (logger.isInfoEnabled()) {
logger.info("Autowired annotation should only be used on methods with parameters: " +
method);
}
}
// 解析@Autowired注解中的required属性的值
boolean required = determineRequiredStatus(ann);
PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
// 再构造一个 AutowiredMethodElement 对象作为注入点对象存入集合中
currElements.add(new AutowiredMethodElement(method, required, pd));
}
});
// 把父类要进行依赖注入的属性放前面,直到找到Object类这一层
elements.addAll(0, currElements);
targetClass = targetClass.getSuperclass();
}
while (targetClass != null && targetClass != Object.class);
// 将所有的注入点elements集合封装为InjectionMetadata对象返回
return InjectionMetadata.forElements(elements, clazz);
}
注入点进行注入
注入点进行注入是基于InstantiationAwareBeanPostProcessor
接口的postProcessProperties()
方法实现的。
所以在AutowiredAnnotationBeanPostProcessor
类中的postProcessMergedBeanDefinition()
方法中将寻找到的注入点存入injectionMetadataCache
集合中。然后在调用postProcessProperties()
进行进行实际的属性注入
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
// 找注入点(所有被@Autowired注解了的Field或Method),此时就能够从injectionMetadataCache获取到值了
InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
try {
// 进行注入
metadata.inject(bean, beanName, pvs);
}
catch (BeanCreationException ex) {
throw ex;
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", ex);
}
return pvs;
}
findAutowiringMetadata()
方法还是和上面的一样,只是这次就能够从injectionMetadataCache获取到值了。重点看inject()
注入的逻辑,这里其实就是遍历上一步寻找注入点时得到的集合,然后再继续调用element.inject(target, beanName, pvs);
public void inject(Object target, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
Collection<InjectedElement> checkedElements = this.checkedElements;
// injectedElements属性值就是上一步寻找注入点时的结果
Collection<InjectedElement> elementsToIterate =
(checkedElements != null ? checkedElements : this.injectedElements);
if (!elementsToIterate.isEmpty()) {
// 遍历每个注入点进行依赖注入
// @Resource注解才是对应的InjectedElement类;@Autowired注解对应的它的子类AutowiredFieldElement或AutowiredMethodElement,
for (InjectedElement element : elementsToIterate) {
element.inject(target, beanName, pvs);
}
}
}
所以如果是针对@Autowired注解,那么我们应该要看InjectedElement
的子类AutowiredFieldElement
或AutowiredMethodElement
的inject()
方法
首先是针对属性的依赖注入方法AutowiredFieldElement
类的inject()
方法,主要就是根据Field对象去BeanFactory中找到具体的值,然后赋值给这个属性
protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
Field field = (Field) this.member;
Object value;
// 刚开始是没有缓存的,会直接走else语句段
if (this.cached) {
// 对于原型Bean,第一次创建的时候,也找注入点,然后进行注入,此时cached为false,注入完了之后cached为true
// 第二次创建的时候,先找注入点(此时会拿到缓存好的注入点),也就是AutowiredFieldElement对象,此时cache为true,也就进到此处了
// 注入点内并没有缓存被注入的具体Bean对象,而是beanName,这样就能保证注入到不同的原型Bean对象
try {
value = resolvedCachedArgument(beanName, this.cachedFieldValue);
}
catch (NoSuchBeanDefinitionException ex) {
// Unexpected removal of target bean for cached argument -> re-resolve
value = resolveFieldValue(field, bean, beanName);
}
}
else {
// 根据filed从BeanFactory中查到的匹配的Bean对象
// resolveFieldValue()方法中最终会调用到resolveDependency()方法找对象
value = resolveFieldValue(field, bean, beanName);
}
// 反射给filed赋值
if (value != null) {
ReflectionUtils.makeAccessible(field);
field.set(bean, value);
}
}
其实针对方法的AutowiredMethodElement
类的inject()
方法具体实现也类似,利用Method方法中的参数去BeanFactory中找到具体的值,然后在执行方法
protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
// 如果pvs中已经有当前注入点的值了,则跳过注入
if (checkPropertySkipping(pvs)) {
return;
}
Method method = (Method) this.member;
Object[] arguments;
// 缓存中找
if (this.cached) {
try {
arguments = resolveCachedArguments(beanName);
}
catch (NoSuchBeanDefinitionException ex) {
arguments = resolveMethodArguments(method, bean, beanName);
}
}
else {
// 利用Method对象取BeanFactory中找到相应的值
arguments = resolveMethodArguments(method, bean, beanName);
}
if (arguments != null) {
try {
ReflectionUtils.makeAccessible(method);
// 再执行方法
method.invoke(bean, arguments);
}
catch (InvocationTargetException ex) {
throw ex.getTargetException();
}
}
}
接下来就轮到了怎么根据Field和Method对象去BeanFactory中找值了,也就是resolveFieldValue()
方法和resolveMethodArguments()
方法,这两个方法最终都会调用resolveDependency()
方法去找到最终要注入的对象
从BeanFactory中找注入对象
上面Spring原始依赖注入BY_TYPE方式,以及利用@Autowired注解加载属性或方法上,最终都是调用的DefaultListableBeanFactory
类中的resolveDependency
方法,去BeanFactory中找到要注入的值。
@Override
@Nullable
public Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName,
@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {
// 往descriptor中初始化方法参数名字发现器 用来获取方法入参名字的
descriptor.initParameterNameDiscovery(getParameterNameDiscoverer());
// 所需要的类型是Optional,如果字段的类型或方法参数的类型是Optional会有一个单独了处理逻辑
if (Optional.class == descriptor.getDependencyType()) {
return createOptionalDependency(descriptor, requestingBeanName);
}
// 所需要的的类型是ObjectFactory,或ObjectProvider,也会有一个单独的处理逻辑
else if (ObjectFactory.class == descriptor.getDependencyType() ||
ObjectProvider.class == descriptor.getDependencyType()) {
return new DependencyObjectProvider(descriptor, requestingBeanName);
}
else if (javaxInjectProviderClass == descriptor.getDependencyType()) {
return new Jsr330Factory().createDependencyProvider(descriptor, requestingBeanName);
}
// 上面几种特殊情况可以不用太关注,大部分情况下我们的类型都不会是上面的那些情况,核心关注下面else语句段
else {
// 在属性或set方法参数前使用了@Lazy注解,那么则构造一个代理对象并返回,真正使用该代理对象时才进行类型筛选Bean
Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(
descriptor, requestingBeanName);
if (result == null) {
// descriptor表示某个属性或某个set方法
// requestingBeanName表示正在进行依赖注入的Bean
result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
}
return result;
}
}
@Nullable
public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName,
@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {
InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor);
try {
// 如果当前descriptor之前做过依赖注入了,则可以直接取shortcut了,相当于缓存
Object shortcut = descriptor.resolveShortcut(this);
if (shortcut != null) {
return shortcut;
}
// 字段的类型或方法形参的类型
Class<?> type = descriptor.getDependencyType();
// 下面这个if逻辑是处理@Value注解的。获取@Value所指定的值
Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);
if (value != null) {
if (value instanceof String) {
// 占位符填充(${XXX}) 就是用XXX作为key,去Environment对象中找对应的value,如果没有找到就直接返回${XXX}字符串
String strVal = resolveEmbeddedValue((String) value);
BeanDefinition bd = (beanName != null && containsBean(beanName) ?
getMergedBeanDefinition(beanName) : null);
// 解析Spring表达式(#{})
value = evaluateBeanDefinitionString(strVal, bd);
}
// 将value转化为descriptor所对应的类型
TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
try {
return converter.convertIfNecessary(value, type, descriptor.getTypeDescriptor());
}
catch (UnsupportedOperationException ex) {
// A custom TypeConverter which does not support TypeDescriptor resolution...
return (descriptor.getField() != null ?
converter.convertIfNecessary(value, type, descriptor.getField()) :
converter.convertIfNecessary(value, type, descriptor.getMethodParameter()));
}
}
// 如果descriptor所对应的类型是数组、集合、Map这些,就将descriptor对应的类型所匹配的所有bean方法,不用进一步再根据beanName做筛选了
Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
if (multipleBeans != null) {
return multipleBeans;
}
// 根据type去找bean。找到所有Bean,key是beanName, value有可能是bean对象,有可能是beanClass
Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
if (matchingBeans.isEmpty()) {
// 根据type一个bean都没有找到, 同时required还为true,则抛异常
if (isRequired(descriptor)) {
raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
}
return null;
}
String autowiredBeanName;
Object instanceCandidate;
if (matchingBeans.size() > 1) {
// 根据类型找到了多个Bean,进一步筛选出某一个, @Primary-->优先级最高--->name
autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);
if (autowiredBeanName == null) {
// 如果没有找打bean,同时required还为true,则抛异常
if (isRequired(descriptor) || !indicatesMultipleBeans(type)) {
return descriptor.resolveNotUnique(descriptor.getResolvableType(), matchingBeans);
}
else {
// In case of an optional Collection/Map, silently ignore a non-unique case:
// possibly it was meant to be an empty collection of multiple regular beans
// (before 4.3 in particular when we didn't even look for collection beans).
return null;
}
}
instanceCandidate = matchingBeans.get(autowiredBeanName);
}
else {
// 表示根据type只找到了一个bean对象
// We have exactly one match.
Map.Entry<String, Object> entry = matchingBeans.entrySet().iterator().next();
autowiredBeanName = entry.getKey();
instanceCandidate = entry.getValue();
}
// 记录匹配过的beanName
if (autowiredBeanNames != null) {
autowiredBeanNames.add(autowiredBeanName);
}
// 有可能筛选出来的是某个bean的类型,此处就进行实例化,调用getBean
if (instanceCandidate instanceof Class) {
instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this);
}
Object result = instanceCandidate;
if (result instanceof NullBean) {
if (isRequired(descriptor)) {
raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
}
result = null;
}
if (!ClassUtils.isAssignableValue(type, result)) {
throw new BeanNotOfRequiredTypeException(autowiredBeanName, type, instanceCandidate.getClass());
}
return result;
}
finally {
ConstructorResolver.setCurrentInjectionPoint(previousInjectionPoint);
}
}
接下来再来看看调用findAutowireCandidates()
方法是如何根据type找bean对象的
protected Map<String, Object> findAutowireCandidates(
@Nullable String beanName, Class<?> requiredType, DependencyDescriptor descriptor) {
// 从BeanFactory中找出和requiredType所匹配的beanName,仅仅是beanName
// 这些bean不一定经过了实例化,只有到最终确定某个Bean了,如果这个Bean还没有实例化才会真正进行实例化
String[] candidateNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this, requiredType, true, descriptor.isEager());
Map<String, Object> result = CollectionUtils.newLinkedHashMap(candidateNames.length);
// 根据类型从resolvableDependencies中匹配Bean,resolvableDependencies中存放的是类型:Bean对象,比如BeanFactory.class:BeanFactory对象,在Spring启动时设置
for (Map.Entry<Class<?>, Object> classObjectEntry : this.resolvableDependencies.entrySet()) {
Class<?> autowiringType = 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;
}
}
}
// 依赖注入 注入自己这种情况下,如果一个type存在多个bean对象,优先考虑的是其他的bean对象
for (String candidate : candidateNames) {
// 如果不是自己,则判断该candidate到底能不能用来进行自动注入。isAutowireCandidate()采用了责任链设计模式
// 因为我们可以使用@Bean注解的autowireCandidate=false来指定当前bean不能参与依赖注入
if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, descriptor)) {
// bean对象添加进result集合中
addCandidateEntry(result, candidate, descriptor, requiredType);
}
}
// 为空要么是真的没有匹配的,要么是匹配的自己
if (result.isEmpty()) {
// 需要匹配的类型是不是Map、数组之类的
boolean multiple = indicatesMultipleBeans(requiredType);
DependencyDescriptor fallbackDescriptor = descriptor.forFallbackMatch();
for (String candidate : candidateNames) {
if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, fallbackDescriptor) &&
(!multiple || getAutowireCandidateResolver().hasQualifier(descriptor))) {
addCandidateEntry(result, candidate, descriptor, requiredType);
}
}
// 匹配的是自己,被自己添加到result中
if (result.isEmpty() && !multiple) {
for (String candidate : candidateNames) {
if (isSelfReference(beanName, candidate) &&
(!(descriptor instanceof MultiElementDescriptor) || !beanName.equals(candidate)) &&
isAutowireCandidate(candidate, fallbackDescriptor)) {
addCandidateEntry(result, candidate, descriptor, requiredType);
}
}
}
}
return result;
}
总结
-
Spring早期依赖注入的两种方式:BY_NAME 和 BY_TYPE
-
寻找所有的注入点,
AutowiredAnnotationBeanPostProcessor.postProcessMergedBeanDefinition()
-
为注入点赋值,入口
AutowiredAnnotationBeanPostProcessor.AutowiredFieldElement.inject()
AutowiredAnnotationBeanPostProcessor.AutowiredMethodElement.inject()
-
处理
@Value
注解,DefaultListableBeanFactory.doResolveDependency()
-
根据type,然后遍历所有的BeanDefinition,找到匹配的beanName集合。
DefaultListableBeanFactory.findAutowireCandidates()
-
判断1,处理@Bean注解的autowireCandidate=false,判断BeanDefinition中的autowireCandidate属性值
SimpleAutowireCandidateResolver.isAutowireCandidate()
-
判断2,处理泛型的情况
GenericTypeAwareAutowireCandidateResolver.isAutowireCandidate()
-
判断3,处理
@Qualifier
注解,QualifierAnnotationAutowireCandidateResolver.isAutowireCandidate()
-
如果经过上面三个筛选之后还剩下多个bean,进一步筛选@Primary–>优先级最高—>name
DefaultListableBeanFactory.determineAutowireCandidate()