目录
- byType源码分析
- @Autowired注解自动装配过程
- 使用方式
- 抛出问题
- @Autowired源码分析
- 第1步:MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition源码分析
- 第1-1步:findAutowiringMetadata在Bean中找到所有@Autowire注解的元数据
- 第1-2步:checkConfigMembers检查元数据中的信息
- 第2步:InstantiationAwareBeanPostProcessor#postProcessPropertyValues
- 第2-1步:findAutowiringMetadata找到所有的@Autowire注解的元数据(从injectionMetadataCache缓存获取)
- 第2-2步:inject属性注入
- resolveDependency方法
- 第1步:findAutowireCandidates,通过Type在工厂中找到所有的候选Bean
- 第3步:Type为普通类型,根据符合的Bean个数做处理
- 第3-3步:determineAutowireCandidate在多个候选Bean中选择
- 总结
本文主要分析byType类型和@Autowire注解的自动装配过程
两者是有相似之处的:都是根据类型选取符合条件的Bean,然后筛选。
不同的是,目标类型有多个Bean符合条件时,byType不会对属性名进行判断直接抛出错误,而@Autowire会再按照属性名筛选。
byType源码分析
protected void autowireByType(
String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
TypeConverter converter = getCustomTypeConverter();
if (converter == null) {
converter = bw;
}
Set<String> autowiredBeanNames = new LinkedHashSet<String>(4);
String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
for (String propertyName : propertyNames) {
try {
PropertyDescriptor pd = bw.getPropertyDescriptor(propertyName);
// Don't try autowiring by type for type Object: never makes sense,
// even if it technically is a unsatisfied, non-simple property.
if (Object.class != pd.getPropertyType()) {
MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd);
// Do not allow eager init for type matching in case of a prioritized post-processor.
boolean eager = !PriorityOrdered.class.isAssignableFrom(bw.getWrappedClass());
DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager);
Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter);
if (autowiredArgument != null) {
pvs.add(propertyName, autowiredArgument);
}
for (String autowiredBeanName : autowiredBeanNames) {
registerDependentBean(autowiredBeanName, beanName);
if (logger.isDebugEnabled()) {
logger.debug("Autowiring by type from bean name '" + beanName + "' via property '" +
propertyName + "' to bean named '" + autowiredBeanName + "'");
}
}
autowiredBeanNames.clear();
}
}
catch (BeansException ex) {
throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName, propertyName, ex);
}
}
}
根据类型自动装配:
- 首先得到 所有需要装配的非简单属性 ,(不是字符串等简单类型)也就是Bean类型的属性,并返回
- 检查此属性的set方法,存在的时候才可自动装配
- 创建一个AutowireByType类型的依赖描述符
- resolveDependency:解析依赖关系 ,返回依赖的Bean实例,这个方法在本篇最后分析。
- 保存返回的依赖Bean实例:pvs.add(propertyName, autowiredArgument)
- 记录依赖关系
- (最后将在applyPropertyValues中实现pvs中的属性注入)
注意,其中有一行DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager);
/**
* Special DependencyDescriptor variant for Spring's good old autowire="byType" mode.
* Always optional; never considering the parameter name for choosing a primary candidate.
*/
@SuppressWarnings("serial")
private static class AutowireByTypeDependencyDescriptor extends DependencyDescriptor {
public AutowireByTypeDependencyDescriptor(MethodParameter methodParameter, boolean eager) {
super(methodParameter, false, eager);
}
@Override
public String getDependencyName() {
return null;
}
}
表示byType形式的依赖描述符有一种特殊的表示: 在选择主要候选对象时从不考虑参数名称!
这句话什么意思呢,就是使用byType形式的自动装配,当此Type的Bean有多个时,将会直接抛出错误,而不是再根据参数的Name去匹配第二遍。
主要是与@Autowired形式的属性注入的特点形成对比,具体分析如下。
@Autowired注解自动装配过程
@Autowired 可以对成员变量、方法以及构造函数进行注释。我们在日常开发的过程中主要使用的是对成员变量的自动装配,即先使用默认构造器创建实例之后,再通过注解使用setter注入属性。
使用方式
@Component
public class Cat {
public String toString() {
return "miao";
}
}
@Component
public class Animal {
@Autowired
private Cat cat;
public Cat getCat() {
return this.cat;
}
public void setCat(Cat cat) {
this.cat = cat;
}
}
public class MainTest {
public static void main(String[] args) {
ApplicationContext ac = new ClassPathXmlApplicationContext("spring/applicationContext.xml");
Animal animal = ac.getBean(Animal.class);
System.out.println(animal.getCat().toString());
}
}
<context:component-scan base-package="*"/>
抛出问题
由上文可知,实现@Autowire类型属性注入的后处理器是AutowiredAnnotationBeanPostProcessor,该接口继承了InstantiationAwareBeanPostProcessor,实现了postProcessPropertyValues方法。
- AutowiredAnnotationBeanPostProcessor何时被注册?
当解析xml配置文件的<context:component-scan />标签时,会将AutowiredAnnotationBeanPostProcessor注册到工厂。 - AutowiredAnnotationBeanPostProcessor何时被调用?
对于@Autowire注解的属性注入,在整个Bean的属性填充中分为两个步骤:
1. 注解的解析
在Spring(四)doCreateBean方法源码分析的第2步:当创建完初始实例之后 ,会进行applyMergedBeanDefinitionPostProcessors:获取全部的MergedBeanDefinitionPostProcessor,然后遍历执行其postProcessMergedBeanDefinition方法。这个方法的意义为对MergedBeanDefinition进行修改,即对 bean定义 进行后期处理。
AutowiredAnnotationBeanPostProcessor继承了MergedBeanDefinitionPostProcessor,在AutowiredAnnotationBeanPostProcessor中的实现即为:对@Autowire注解的Field及Method进行解析,并放入 injectionMetadataCache缓存 中。
2. 属性的注入
在Spring(四)doCreateBean方法源码分析中的第4-3步:InstantiationAwareBeanPostProcessor.postProcessPropertyValues。
AutowiredAnnotationBeanPostProcessor继承了InstantiationAwareBeanPostProcessor,在AutowiredAnnotationBeanPostProcessor中的实现即为:找到被Autowired注解的属性(从injectionMetadataCache缓存中获取),进行属性注入。
@Autowired源码分析
第1步:MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition源码分析
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
if (beanType != null) {
InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null);
metadata.checkConfigMembers(beanDefinition);
}
}
方法包括了:
- findAutowiringMetadata在Bean中找到所有@Autowire注解的元数据
- checkConfigMembers检查元数据中的信息
第1-1步:findAutowiringMetadata在Bean中找到所有@Autowire注解的元数据
private InjectionMetadata findAutowiringMetadata(String beanName, Class<?> clazz, PropertyValues pvs) {
// Fall back to class name as cache key, for backwards compatibility with custom callers.
String cacheKey = (StringUtils.hasLength(beanName) ? beanName : clazz.getName());
// Quick check on the concurrent map first, with minimal locking.
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);
}
try {
metadata = buildAutowiringMetadata(clazz);
this.injectionMetadataCache.put(cacheKey, metadata);
}
catch (NoClassDefFoundError err) {
throw new IllegalStateException("Failed to introspect bean class [" + clazz.getName() +
"] for autowiring metadata: could not find class that it depends on", err);
}
}
}
}
return metadata;
}
目标元数据使用缓存存储,关键的解析注解生成元数据的方法是buildAutowiringMetadata:
private InjectionMetadata buildAutowiringMetadata(final Class<?> clazz) {
LinkedList<InjectionMetadata.InjectedElement> elements = new LinkedList<InjectionMetadata.InjectedElement>();
Class<?> targetClass = clazz;
do {
final LinkedList<InjectionMetadata.InjectedElement> currElements =
new LinkedList<InjectionMetadata.InjectedElement>();
ReflectionUtils.doWithLocalFields(targetClass, new ReflectionUtils.FieldCallback() {
@Override
public void doWith(Field field) throws IllegalArgumentException, IllegalAccessException {
AnnotationAttributes ann = findAutowiredAnnotation(field);
if (ann != null) {
if (Modifier.isStatic(field.getModifiers())) {
if (logger.isWarnEnabled()) {
logger.warn("Autowired annotation is not supported on static fields: " + field);
}
return;
}
boolean required = determineRequiredStatus(ann);
currElements.add(new AutowiredFieldElement(field, required));
}
}
});
ReflectionUtils.doWithLocalMethods(targetClass, new ReflectionUtils.MethodCallback() {
@Override
public void doWith(Method method) throws IllegalArgumentException, IllegalAccessException {
Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
if (!BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) {
return;
}
AnnotationAttributes ann = findAutowiredAnnotation(bridgedMethod);
if (ann != null && method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
if (Modifier.isStatic(method.getModifiers())) {
if (logger.isWarnEnabled()) {
logger.warn("Autowired annotation is not supported on static methods: " + method);
}
return;
}
if (method.getParameterTypes().length == 0) {
if (logger.isWarnEnabled()) {
logger.warn("Autowired annotation should be used on methods with parameters: " + method);
}
}
boolean required = determineRequiredStatus(ann);
PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
currElements.add(new AutowiredMethodElement(method, required, pd));
}
}
});
elements.addAll(0, currElements);
targetClass = targetClass.getSuperclass();
}
while (targetClass != null && targetClass != Object.class);
return new InjectionMetadata(clazz, elements);
}
关注上半部分,doWithLocalFields,找到Bean中带有注解的属性。其中的findAutowiredAnnotation是通过匹配注解找属性的方法。
找到之后进行两个操作:
- 判断属性是否是Static,如果是静态的,则抛出错误
- 判断属性是否是required,将Required与Field一起包装成AutowiredFieldElement返回
最后将找到的被注解Field存入到 injectionMetadataCache 中,以供真正的属性注入时使用。
第1-2步:checkConfigMembers检查元数据中的信息
public void checkConfigMembers(RootBeanDefinition beanDefinition) {
Set<InjectedElement> checkedElements = new LinkedHashSet<InjectedElement>(this.injectedElements.size());
for (InjectedElement element : this.injectedElements) {
Member member = element.getMember();
if (!beanDefinition.isExternallyManagedConfigMember(member)) {
beanDefinition.registerExternallyManagedConfigMember(member);
checkedElements.add(element);
if (logger.isDebugEnabled()) {
logger.debug("Registered injected element on class [" + this.targetClass.getName() + "]: " + element);
}
}
}
this.checkedElements = checkedElements;
}
遍历上一步中Elements属性,将其注册到BeanDefinition的 externallyManagedConfigMembers,checkedElements 属性中以供后续使用。
第2步:InstantiationAwareBeanPostProcessor#postProcessPropertyValues
public PropertyValues postProcessPropertyValues(
PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
try {
metadata.inject(bean, beanName, pvs);
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", ex);
}
return pvs;
}
此方法中包括了:
- findAutowiringMetadata找到所有的@Autowire注解的元数据
- inject属性注入
第2-1步:findAutowiringMetadata找到所有的@Autowire注解的元数据(从injectionMetadataCache缓存获取)
第2-2步:inject属性注入
public void inject(Object target, String beanName, PropertyValues pvs) throws Throwable {
Collection<InjectedElement> elementsToIterate =
(this.checkedElements != null ? this.checkedElements : this.injectedElements);
if (!elementsToIterate.isEmpty()) {
boolean debug = logger.isDebugEnabled();
for (InjectedElement element : elementsToIterate) {
if (debug) {
logger.debug("Processing injected element of bean '" + beanName + "': " + element);
}
element.inject(target, beanName, pvs);
}
}
}
此方法中:遍历BeanDefinition中解析到的checkedElements,依次进行element.inject(target, beanName, pvs);
Field类型的Element会进入到AutowiredFieldElement.inject方法:
protected void inject(Object bean, String beanName, PropertyValues pvs) throws Throwable {
Field field = (Field) this.member;
try {
Object value;
if (this.cached) {
value = resolvedCachedArgument(beanName, this.cachedFieldValue);
}
else {
DependencyDescriptor desc = new DependencyDescriptor(field, this.required);
desc.setContainingClass(bean.getClass());
Set<String> autowiredBeanNames = new LinkedHashSet<String>(1);
TypeConverter typeConverter = beanFactory.getTypeConverter();
value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
synchronized (this) {
if (!this.cached) {
if (value != null || this.required) {
this.cachedFieldValue = desc;
registerDependentBeans(beanName, autowiredBeanNames);
if (autowiredBeanNames.size() == 1) {
String autowiredBeanName = autowiredBeanNames.iterator().next();
if (beanFactory.containsBean(autowiredBeanName)) {
if (beanFactory.isTypeMatch(autowiredBeanName, field.getType())) {
this.cachedFieldValue = new RuntimeBeanReference(autowiredBeanName);
}
}
}
}
else {
this.cachedFieldValue = null;
}
this.cached = true;
}
}
}
if (value != null) {
ReflectionUtils.makeAccessible(field);
field.set(bean, value);
}
}
catch (Throwable ex) {
throw new BeanCreationException("Could not autowire field: " + field, ex);
}
}
根据@Autowire注解装配:
- 首先 在缓存中找到所有被@Autowire注解的属性
- 创建一个依赖描述符
- resolveDependency:解析依赖关系 ,返回依赖的Bean实例
- 记录依赖关系
- 在此处直接通过 反射 给Bean的属性赋值
注意,这种依赖描述符无特殊处理,getDependencyName会返回Filed的名字,默认实现:
/**
* Determine the name of the wrapped parameter/field.
* @return the declared name (never {@code null})
*/
public String getDependencyName() {
return (this.field != null ? this.field.getName() : this.methodParameter.getParameterName());
}
resolveDependency方法
resolveDependency主要是通过Type类型,来解析依赖关系。用于byType类型的自动装配、@Autowired注解方式的自动装配。
resolveDependency方法中的核心步骤doResolveDependency:
public Object doResolveDependency(DependencyDescriptor descriptor, String beanName,
Set<String> autowiredBeanNames, TypeConverter typeConverter) throws BeansException {
Class<?> type = descriptor.getDependencyType();
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());
return (descriptor.getField() != null ?
converter.convertIfNecessary(value, type, descriptor.getField()) :
converter.convertIfNecessary(value, type, descriptor.getMethodParameter()));
}
if (type.isArray()) {
Class<?> componentType = type.getComponentType();
DependencyDescriptor targetDesc = new DependencyDescriptor(descriptor);
targetDesc.increaseNestingLevel();
Map<String, Object> matchingBeans = findAutowireCandidates(beanName, componentType, targetDesc);
if (matchingBeans.isEmpty()) {
if (descriptor.isRequired()) {
raiseNoSuchBeanDefinitionException(componentType, "array of " + componentType.getName(), descriptor);
}
return null;
}
if (autowiredBeanNames != null) {
autowiredBeanNames.addAll(matchingBeans.keySet());
}
TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
Object result = converter.convertIfNecessary(matchingBeans.values(), type);
if (getDependencyComparator() != null && result instanceof Object[]) {
Arrays.sort((Object[]) result, adaptDependencyComparator(matchingBeans));
}
return result;
}
else if (Collection.class.isAssignableFrom(type) && type.isInterface()) {
Class<?> elementType = descriptor.getCollectionType();
if (elementType == null) {
if (descriptor.isRequired()) {
throw new FatalBeanException("No element type declared for collection [" + type.getName() + "]");
}
return null;
}
DependencyDescriptor targetDesc = new DependencyDescriptor(descriptor);
targetDesc.increaseNestingLevel();
Map<String, Object> matchingBeans = findAutowireCandidates(beanName, elementType, targetDesc);
if (matchingBeans.isEmpty()) {
if (descriptor.isRequired()) {
raiseNoSuchBeanDefinitionException(elementType, "collection of " + elementType.getName(), descriptor);
}
return null;
}
if (autowiredBeanNames != null) {
autowiredBeanNames.addAll(matchingBeans.keySet());
}
TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
Object result = converter.convertIfNecessary(matchingBeans.values(), type);
if (getDependencyComparator() != null && result instanceof List) {
Collections.sort((List<?>) result, adaptDependencyComparator(matchingBeans));
}
return result;
}
else if (Map.class.isAssignableFrom(type) && type.isInterface()) {
Class<?> keyType = descriptor.getMapKeyType();
if (String.class != keyType) {
if (descriptor.isRequired()) {
throw new FatalBeanException("Key type [" + keyType + "] of map [" + type.getName() +
"] must be [java.lang.String]");
}
return null;
}
Class<?> valueType = descriptor.getMapValueType();
if (valueType == null) {
if (descriptor.isRequired()) {
throw new FatalBeanException("No value type declared for map [" + type.getName() + "]");
}
return null;
}
DependencyDescriptor targetDesc = new DependencyDescriptor(descriptor);
targetDesc.increaseNestingLevel();
Map<String, Object> matchingBeans = findAutowireCandidates(beanName, valueType, targetDesc);
if (matchingBeans.isEmpty()) {
if (descriptor.isRequired()) {
raiseNoSuchBeanDefinitionException(valueType, "map with value type " + valueType.getName(), descriptor);
}
return null;
}
if (autowiredBeanNames != null) {
autowiredBeanNames.addAll(matchingBeans.keySet());
}
return matchingBeans;
}
else {
Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
if (matchingBeans.isEmpty()) {
if (descriptor.isRequired()) {
raiseNoSuchBeanDefinitionException(type, "", descriptor);
}
return null;
}
if (matchingBeans.size() > 1) {
String primaryBeanName = determineAutowireCandidate(matchingBeans, descriptor);
if (primaryBeanName == null) {
throw new NoUniqueBeanDefinitionException(type, matchingBeans.keySet());
}
if (autowiredBeanNames != null) {
autowiredBeanNames.add(primaryBeanName);
}
return matchingBeans.get(primaryBeanName);
}
// We have exactly one match.
Map.Entry<String, Object> entry = matchingBeans.entrySet().iterator().next();
if (autowiredBeanNames != null) {
autowiredBeanNames.add(entry.getKey());
}
return entry.getValue();
}
}
方法很长,包括如下功能:
- findAutowireCandidates,找到 所有匹配Type的所有Bean ,返回matchingBeans:一个Map<String, Object>
- 如果属性的类型是「数组、集合、Map」,只要matchingBeans不为空则直接返回
- 重点看依赖是普通Bean类型的情况
第1步:findAutowireCandidates,通过Type在工厂中找到所有的候选Bean
protected Map<String, Object> findAutowireCandidates(
String beanName, Class<?> requiredType, DependencyDescriptor descriptor) {
String[] candidateNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this, requiredType, true, descriptor.isEager());
Map<String, Object> result = new LinkedHashMap<String, Object>(candidateNames.length);
for (Class<?> autowiringType : this.resolvableDependencies.keySet()) {
if (autowiringType.isAssignableFrom(requiredType)) {
Object autowiringValue = this.resolvableDependencies.get(autowiringType);
autowiringValue = AutowireUtils.resolveAutowiringValue(autowiringValue, requiredType);
if (requiredType.isInstance(autowiringValue)) {
result.put(ObjectUtils.identityToString(autowiringValue), autowiringValue);
break;
}
}
}
for (String candidateName : candidateNames) {
if (!isSelfReference(beanName, candidateName) && isAutowireCandidate(candidateName, descriptor)) {
result.put(candidateName, getBean(candidateName));
}
}
if (result.isEmpty()) {
DependencyDescriptor fallbackDescriptor = descriptor.forFallbackMatch();
for (String candidateName : candidateNames) {
if (!candidateName.equals(beanName) && isAutowireCandidate(candidateName, fallbackDescriptor)) {
result.put(candidateName, getBean(candidateName));
}
}
}
return result;
}
第3步:Type为普通类型,根据符合的Bean个数做处理
Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
if (matchingBeans.isEmpty()) {
if (descriptor.isRequired()) {
raiseNoSuchBeanDefinitionException(type, "", descriptor);
}
return null;
}
if (matchingBeans.size() > 1) {
String primaryBeanName = determineAutowireCandidate(matchingBeans, descriptor);
if (primaryBeanName == null) {
throw new NoUniqueBeanDefinitionException(type, matchingBeans.keySet());
}
if (autowiredBeanNames != null) {
autowiredBeanNames.add(primaryBeanName);
}
return matchingBeans.get(primaryBeanName);
}
// We have exactly one match.
Map.Entry<String, Object> entry = matchingBeans.entrySet().iterator().next();
if (autowiredBeanNames != null) {
autowiredBeanNames.add(entry.getKey());
}
return entry.getValue();
- 如果matchingBeans(即工厂中此Type的Bean)是空,而属性又是Required,则抛出错误;
- 如果matchingBeans正好为1个,则将此matchingBean加入到autowiredBeanNames中返回;
- 如果matchingBeans有多个,determineAutowireCandidate在多个候选Bean中选择一个,选择的策略为determineAutowireCandidate
第3-3步:determineAutowireCandidate在多个候选Bean中选择
protected String determineAutowireCandidate(Map<String, Object> candidateBeans, DependencyDescriptor descriptor) {
Class<?> requiredType = descriptor.getDependencyType();
String primaryCandidate = determinePrimaryCandidate(candidateBeans, requiredType);
if (primaryCandidate != null) {
return primaryCandidate;
}
String priorityCandidate = determineHighestPriorityCandidate(candidateBeans, requiredType);
if (priorityCandidate != null) {
return priorityCandidate;
}
// Fallback
for (Map.Entry<String, Object> entry : candidateBeans.entrySet()) {
String candidateBeanName = entry.getKey();
Object beanInstance = entry.getValue();
if ((beanInstance != null && this.resolvableDependencies.containsValue(beanInstance)) ||
matchesBeanName(candidateBeanName, descriptor.getDependencyName())) {
return candidateBeanName;
}
}
return null;
}
可以很清晰地看到选择Bean的策略为:
- 找加了@Primary注解的bean;
- 找加了@Priority注解的bean;
- 根据属性的名称和Spring中的beanName是否相等来判断;
如果上述三个方法都不能确定唯一的Bean,则会抛出异常
在第三种情况中,判断两个name是否相等的代码:
matchesBeanName(candidateBeanName, descriptor.getDependencyName())
注意:byType类型的descriptor.getDependencyName(),上文已经说明,被重写为return null;所以byType类型的自动装配无论名字是否相同,最后都将返回空,也就是抛出错误:NoUniqueBeanDefinitionException。
所以说,@Autowired注解是先根据类型注入,当碰到多个相同类型时,就会根据属性名注入 。
总结
byType与Autowired注解是有些相似之处的
- 它们的本质都是通过Type找到所有符合条件的Bean,然后再进行筛选。
不同之处在于
- byType类型的自动装配是我们在xml中配置的属性标签所声明,在xml配置解析的过程中已经被解析到了BeanDefintion中;而@Autowired是一个注解,只能使用 后置处理器去解析注解 属性,进行处理。
- byType类型的自动装配通过resolveDependency找到所依赖的Bean对象之后,会存入到PropertyValues中,等到属性填充方法populateBean的最后applyPropertyValues时再统一的应用;而@Autowired通过resolveDependency找到所依赖的Bean对象之后,会直接通过反射将属性赋值,而不再存入PropertyValues。
- byType类型不会对属性名称进行判断;而@Autowired当找到有多个此类型的Bean时,会再按照属性名进行筛选。