上一篇文章Spring系列-依赖注入实现原理-XML配置我们讲解了通过配置文件进行依赖注入的原理,这篇文章我们就讲解一下Spring通过注解进行依赖注入的实现原理。
还是拿我们之前用的类举例:
@Component
public class Home {
@Autowired
private User user;
}
@Component
public class User {
@Value("${name}")
private String name;
@Value("${age}")
private String age;
}
spring.properties
name: jack
age: 18
populateBean()
依赖注入的方法入口还是populateBean()方法,但是注解方式和XML配置方式不同的是,这次执行的代码逻辑的位置变了。前面将XML配置自动注入的时候,又是自动注入,又是applyPropertyValues(),注解方式不是了,注解方式走的是上一章中我们没怎么说的后置处理器流程。
// AbstractAutowireCapableBeanFactory.java
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
// ... 忽略和xml配置有关的代码
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);
PropertyDescriptor[] filteredPds = null;
if (hasInstAwareBpps) {
if (pvs == null) {
pvs = mbd.getPropertyValues();
}
// 注解方式这里是重点,通过InstantiationAwareBeanPostProcessor的postProcessProperties()进行了处理,在该方法中
// 完成了@Autowired @Value @Resource等注解的自动注入
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
// postProcessProperties()中处理注入
PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
if (filteredPds == null) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
return;
}
}
pvs = pvsToUse;
}
}
}
if (needsDepCheck) {
if (filteredPds == null) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
checkDependencies(beanName, mbd, filteredPds, pvs);
}
if (pvs != null) {
applyPropertyValues(beanName, mbd, bw, pvs);
}
}
InstantiationAwareBeanPostProcessor
注解方式的自动注入主要涉及两个后置处理器:
-
AutowiredAnnotationBeanPostProcessor
该后置处理器会处理@Autowired和@Value方式的注入
-
CommonAnnotationBeanPostProcessor
该后置处理器会处理@Resource方式的注入
接下来我们以AutowiredAnnotationBeanPostProcessor为例进行讲解,CommonAnnotationBeanPostProcessor的处理逻辑类似。
AutowiredAnnotationBeanPostProcessor
首先在创建AutowiredAnnotationBeanPostProcessor后置处理器的时候,就会设置该处理器要处理的注解类型。
// AutowiredAnnotationBeanPostProcessor.java
public AutowiredAnnotationBeanPostProcessor() {
// 处理@Autowired
this.autowiredAnnotationTypes.add(Autowired.class);
// 处理@Value
this.autowiredAnnotationTypes.add(Value.class);
try {
this.autowiredAnnotationTypes.add((Class<? extends Annotation>)
ClassUtils.forName("javax.inject.Inject", AutowiredAnnotationBeanPostProcessor.class.getClassLoader()));
logger.trace("JSR-330 'javax.inject.Inject' annotation found and supported for autowiring");
}
catch (ClassNotFoundException ex) {
// JSR-330 API not available - simply skip.
}
}
接下来我们回到逻辑中调用的postProcessProperties()方法。
postProcessProperties()
在该方法中,会实现注解的依赖注入逻辑。
注意:注解方式在这一步就已经完成了注入,不会再通过前面讲的XML方式的applyPropertyValues()方法进行注入。
// AutowiredAnnotationBeanPostProcessor.java
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
// 获取需要注入的元数据。
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()
查询需要注入的属性元数据,用来执行执行接下来的注入。其实在执行postProcessProperties()之前,已经执行了postProcessMergedBeanDefinition()方法,该方法已经执行过findAutowiringMetadata()方法,所以在这里可以直接从缓存中获取到。
// AutowiredAnnotationBeanPostProcessor.java
private InjectionMetadata findAutowiringMetadata(String beanName, Class<?> clazz, @Nullable PropertyValues pvs) {
// 回退到类名作为缓存键,以向后兼容自定义调用者
String cacheKey = (StringUtils.hasLength(beanName) ? beanName : clazz.getName());
// 首先从缓存中获取,如果之前处理过就会存在
InjectionMetadata metadata = this.injectionMetadataCache.get(cacheKey);
// 看缓存中的注入元数据信息是否需要刷新,如果metadata不存在,或者metadata中的class和传入的clazz不一致,就需要刷新
if (InjectionMetadata.needsRefresh(metadata, clazz)) {
synchronized (this.injectionMetadataCache) {
metadata = this.injectionMetadataCache.get(cacheKey);
// double check
if (InjectionMetadata.needsRefresh(metadata, clazz)) {
if (metadata != null) {
// 将pvs中的已处理集合中的该属性清除,之后还要处理
metadata.clear(pvs);
}
// 构建注入元数据
metadata = buildAutowiringMetadata(clazz);
// 方法缓存
this.injectionMetadataCache.put(cacheKey, metadata);
}
}
}
return metadata;
}
buildAutowiringMetadata()
该方法整体逻辑非常简单,就是通过反射获取该类中的所有字段和方法(包括父类),将字段或方法上标有@Autowired或@Value注解的找出来,封装为InjectedElement添加到elements集合中返回。返回的就是所有需要注入的属性和方法信息。
// AutowiredAnnotationBeanPostProcessor.java
private InjectionMetadata buildAutowiringMetadata(final Class<?> clazz) {
// 如果clazz不符合条件,直接忽略处理
// 什么样的符合条件?clazz全类名不是java.开头并且不是Ordered.class的就符合条件
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<>();
// 反射处理所有的字段
ReflectionUtils.doWithLocalFields(targetClass, field -> {
// 获取字段上的注解 @Autowired @Value
MergedAnnotation<?> ann = findAutowiredAnnotation(field);
if (ann != null) {
// 不处理静态字段,也就是注解添加到静态字段上无效
if (Modifier.isStatic(field.getModifiers())) {
if (logger.isInfoEnabled()) {
logger.info("Autowired annotation is not supported on static fields: " + field);
}
return;
}
// 推断是否是必须的,像@Value没有required属性,则为true
boolean required = determineRequiredStatus(ann);
// 将字段信息封装为AutowiredFieldElement,添加到currElements集合中,等待后续注入
currElements.add(new AutowiredFieldElement(field, required));
}
});
// 反射处理所有的方法
ReflectionUtils.doWithLocalMethods(targetClass, method -> {
// 注意:这里是获取被桥接的方法,不是获取桥接方法
// 至于什么是桥接方法,我们也许后面会讲,它是为了即满足java语言特性又符合JVM特性而由编译器自动生成的一种方法
// 所以我们在反射获取方法时,如果存在桥接方法,会将桥接方法也获取出来,这里就是如果是桥接方法,获取该桥接方法
// 桥接的那个方法
Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
// 这里是为了判断由于可见性生成的桥接方法,如果是这种原因生成的桥接方法,可以把该桥接方法当做被桥接方法处理
if (!BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) {
return;
}
// 获取方法上的注解 @Autowired @Value
MergedAnnotation<?> ann = findAutowiredAnnotation(bridgedMethod);
if (ann != null && method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
// 不处理静态方法,也就是注解添加到静态方法上无效
if (Modifier.isStatic(method.getModifiers())) {
if (logger.isInfoEnabled()) {
logger.info("Autowired annotation is not supported on static methods: " + method);
}
return;
}
if (method.getParameterCount() == 0) {
if (logger.isInfoEnabled()) {
logger.info("Autowired annotation should only be used on methods with parameters: " +
method);
}
}
// 推断是否是必须的,像@Value没有required属性,则为true
boolean required = determineRequiredStatus(ann);
// 获取方法的属性描述对象
PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
// 将方法信息封装为AutowiredMethodElement(不是字段的AutowiredFieldElement),添加到currElements集合中,
// 等待后续注入
currElements.add(new AutowiredMethodElement(method, required, pd));
}
});
elements.addAll(0, currElements);
// 如果该类还有父类,循环处理父类字段和方法
targetClass = targetClass.getSuperclass();
}
while (targetClass != null && targetClass != Object.class);
// 将需要注入的类和字段以及方法信息封装到InjectionMetadata中,以便注入处理
return InjectionMetadata.forElements(elements, clazz);
}
findAutowiredAnnotation()
// AutowiredAnnotationBeanPostProcessor.java
private MergedAnnotation<?> findAutowiredAnnotation(AccessibleObject ao) {
// 通过字段或方法对象获取处理后的注解
// 合并注解什么意思?就是一个注解可能依赖于另一个注解,在处理的时候会将这两个注解合并处理
MergedAnnotations annotations = MergedAnnotations.from(ao);
// 如果存在需要处理的注解,则返回该注解。可以看到这里只会返回一个注解,先后顺序依赖于autowiredAnnotationTypes中注解的顺序
// 这里默认的顺序就是@Autowired @Value
for (Class<? extends Annotation> type : this.autowiredAnnotationTypes) {
MergedAnnotation<?> annotation = annotations.get(type);
if (annotation.isPresent()) {
return annotation;
}
}
return null;
}
metadata.inject()
// AutowiredAnnotationBeanPostProcessor.java
public void inject(Object target, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
// 如果已校验的元素不为null,则以已校验的元素为准进行处理,否则以前面获取的注入的元素为准
// 已校验的元素是怎么来的?其实这里又涉及到了postProcessMergedBeanDefinition(), 在该方法中调用完
// findAutowiringMetadata()方法后又调用了一个metadata.checkConfigMembers()方法,就是在checkConfigMembers()
// 方法中校验了需要校验了主要注入的元素,并赋值给checkedElements。
Collection<InjectedElement> checkedElements = this.checkedElements;
Collection<InjectedElement> elementsToIterate =
(checkedElements != null ? checkedElements : this.injectedElements);
if (!elementsToIterate.isEmpty()) {
for (InjectedElement element : elementsToIterate) {
if (logger.isTraceEnabled()) {
logger.trace("Processing injected element of bean '" + beanName + "': " + element);
}
// 循环每一个需要注入的元素,执行注入逻辑
element.inject(target, beanName, pvs);
}
}
}
checkConfigMembers()
该方法其实就是判断哪些元素还需要进行注入,因为一个字段或方法上可能有多个注入注解,如果已经由其它注解执行过注入了,在这里就不用再次执行了,以第一次执行的为准。主要是依靠BeanDefinition中的externallyManagedConfigMembers集合进行判断,执行过注入的字段或方法会放到这个集合中。相关字段我们已经在Spring系列-BeanDefinition详解中解释过了。
// InjectionMetadata.java
public void checkConfigMembers(RootBeanDefinition beanDefinition) {
Set<InjectedElement> checkedElements = new LinkedHashSet<>(this.injectedElements.size());
for (InjectedElement element : this.injectedElements) {
Member member = element.getMember();
// 判断该字段或方法是否已经在externallyManagedConfigMembers集合中存在了,如果已经存在就不再处理了
if (!beanDefinition.isExternallyManagedConfigMember(member)) {
beanDefinition.registerExternallyManagedConfigMember(member);
checkedElements.add(element);
if (logger.isTraceEnabled()) {
logger.trace("Registered injected element on class [" + this.targetClass.getName() + "]: " + element);
}
}
}
// 将需要处理的字段或方法赋值给checkedElements
this.checkedElements = checkedElements;
}
element.inject()
对于@Autowired @Value注解来说,执行的是AutowiredFieldElement或AutowiredMethodElement中重写后的inject()逻辑。下面以AutowiredFieldElement中重写的inject()进行说明。
// AutowiredFieldElement.java
protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
Field field = (Field) this.member;
Object value;
// 如果cached为true,说明之前处理过,并且通过上一次的处理知道了该次可以简化依赖的解析逻辑
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<>(1);
Assert.state(beanFactory != null, "No BeanFactory available");
TypeConverter typeConverter = beanFactory.getTypeConverter();
try {
// (重点:)解析依赖值,上一节xml配置中我们也说到了这个方法,这一节我们就看一下这个方法是怎么实现的。
value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
}
catch (BeansException ex) {
throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(field), ex);
}
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();
// 如果beanFactory中存在并且类型一致,则创建ShortcutDependencyDescriptor并将cached设置为true
// 便于简化resolveDependency()解析
if (beanFactory.containsBean(autowiredBeanName) &&
beanFactory.isTypeMatch(autowiredBeanName, field.getType())) {
this.cachedFieldValue = new ShortcutDependencyDescriptor(
desc, autowiredBeanName, field.getType());
}
}
}
else {
this.cachedFieldValue = null;
}
this.cached = true;
}
}
}
// 通过这里可以看到,最终其实还是通过反射进行了属性赋值
if (value != null) {
ReflectionUtils.makeAccessible(field);
field.set(bean, value);
}
}
}
resolveDependency()
其中的重点方法为doResolveDependency(),无论是什么情况,最终都是调用doResolveDependency()方法进行解析。
// DefaultListableBeanFactory.java
public Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName,
@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {
// getParameterNameDiscoverer()是用来解析方法参数实际名称用的
descriptor.initParameterNameDiscovery(getParameterNameDiscoverer());
// 处理Optional类型的注入,其最终也是调用了doResolveDependency()方法,只是对最后的返回值进行了Optional处理
// createOptionalDependency()方法中还对嵌套进行了处理,例如:Optional<Optional<User>>
if (Optional.class == descriptor.getDependencyType()) {
return createOptionalDependency(descriptor, requestingBeanName);
}
// 处理ObjectFactory或ObjectProvider类型的注入
// 这两种类型的注入可以解决懒加载的问题,也可以处理注入属性为null的问题,后面讲解
// 其最终也是调用了doResolveDependency()方法,还处理了Optional问题,只是需要调用DependencyObjectProvider的
// getObject()方法才会触发执行
else if (ObjectFactory.class == descriptor.getDependencyType() ||
ObjectProvider.class == descriptor.getDependencyType()) {
return new DependencyObjectProvider(descriptor, requestingBeanName);
}
// 处理javax.inject.Provider类型的注入,同ObjectProvider,只是这是Jsr330定义的标准
else if (javaxInjectProviderClass == descriptor.getDependencyType()) {
return new Jsr330Factory().createDependencyProvider(descriptor, requestingBeanName);
}
else {
// 看是否需要懒加载,就是看是否存在@Lazy注解
Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(
descriptor, requestingBeanName);
if (result == null) {
// 如果不需要懒加载,立即开始解析
result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
}
return result;
}
}
doResolveDependency()
// DefaultListableBeanFactory.java
public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName,
@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {
// 将当前依赖描述对象设置为注入点,返回上一个注入点
InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor);
try {
// 如果有解析快照,直接返回快照,说明之前已经解析过
Object shortcut = descriptor.resolveShortcut(this);
if (shortcut != null) {
return shortcut;
}
Class<?> type = descriptor.getDependencyType();
// 这一步默认情况下实际就是获取@Value注解中设置的value值
Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);
if (value != null) {
// 如果解析的值是String类型,如果是@Value注解,肯定是String类型
if (value instanceof String) {
// 例如:@Value("${name}") 这里就会将${name}解析为配置文件中的name值,替换占位符
String strVal = resolveEmbeddedValue((String) value);
BeanDefinition bd = (beanName != null && containsBean(beanName) ?
getMergedBeanDefinition(beanName) : null);
// 这里会解析el表达式#{}
value = evaluateBeanDefinitionString(strVal, bd);
}
// 获取类型转化器
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()));
}
}
// 解析Stream、Array、Collection、Map类型的注入,大体逻辑也是会通过findAutowireCandidates()找到候选者,然后
// 进行过滤、Bean实例化,类型转换,排序等处理
Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
if (multipleBeans != null) {
return multipleBeans;
}
// 发现注入候选Bean,在resolveMultipleBeans()方法中也会调用该方法
Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
if (matchingBeans.isEmpty()) {
// 如果没有找到符合条件的Bean,又标明了必须要注入,则报错
if (isRequired(descriptor)) {
raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
}
return null;
}
String autowiredBeanName;
Object instanceCandidate;
// 走到这里,一定不是集合类型的注入,所以这里如果发现该属性匹配到多个符合条件的Bean,需要推断一下注入哪一个
if (matchingBeans.size() > 1) {
// 推断注入哪一个,@Primary优先级最高, 其次@Priority(PriorityOrdered、Ordered接口),否则判断该候选
// 是否在可解析依赖集合或者名称匹配
autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);
if (autowiredBeanName == null) {
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 {
// 如果只匹配到一个,就正常处理
Map.Entry<String, Object> entry = matchingBeans.entrySet().iterator().next();
autowiredBeanName = entry.getKey();
instanceCandidate = entry.getValue();
}
// 将符合条件的Bean名称添加到autowiredBeanNames集合
if (autowiredBeanNames != null) {
autowiredBeanNames.add(autowiredBeanName);
}
// 如果value还是个Class类型,则需要从beanFactory获取要注入的实例对象
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);
}
}
resolveMultipleBeans()
// DefaultListableBeanFactory.java
private Object resolveMultipleBeans(DependencyDescriptor descriptor, @Nullable String beanName,
@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) {
Class<?> type = descriptor.getDependencyType();
// 处理Stream类型
if (descriptor instanceof StreamDependencyDescriptor) {
// 查找候选者
Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
if (autowiredBeanNames != null) {
autowiredBeanNames.addAll(matchingBeans.keySet());
}
Stream<Object> stream = matchingBeans.keySet().stream()
// 实例化Bean
.map(name -> descriptor.resolveCandidate(name, type, this))
// 过滤NullBean
.filter(bean -> !(bean instanceof NullBean));
// 排序
if (((StreamDependencyDescriptor) descriptor).isOrdered()) {
stream = stream.sorted(adaptOrderComparator(matchingBeans));
}
return stream;
}
// 处理数组类型
else if (type.isArray()) {
Class<?> componentType = type.getComponentType();
ResolvableType resolvableType = descriptor.getResolvableType();
Class<?> resolvedArrayType = resolvableType.resolve(type);
if (resolvedArrayType != type) {
componentType = resolvableType.getComponentType().resolve();
}
if (componentType == null) {
return null;
}
// 查找候选者, 注意这里创建的就是MultiElementDescriptor类型
Map<String, Object> matchingBeans = findAutowireCandidates(beanName, componentType,
new MultiElementDescriptor(descriptor));
if (matchingBeans.isEmpty()) {
return null;
}
if (autowiredBeanNames != null) {
autowiredBeanNames.addAll(matchingBeans.keySet());
}
TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
// 类型转换
Object result = converter.convertIfNecessary(matchingBeans.values(), resolvedArrayType);
if (result instanceof Object[]) {
Comparator<Object> comparator = adaptDependencyComparator(matchingBeans);
// 排序
if (comparator != null) {
Arrays.sort((Object[]) result, comparator);
}
}
return result;
}
// 处理集合类型
else if (Collection.class.isAssignableFrom(type) && type.isInterface()) {
Class<?> elementType = descriptor.getResolvableType().asCollection().resolveGeneric();
if (elementType == null) {
return null;
}
// 查找候选者
Map<String, Object> matchingBeans = findAutowireCandidates(beanName, elementType,
new MultiElementDescriptor(descriptor));
if (matchingBeans.isEmpty()) {
return null;
}
if (autowiredBeanNames != null) {
autowiredBeanNames.addAll(matchingBeans.keySet());
}
TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
// 类型转换
Object result = converter.convertIfNecessary(matchingBeans.values(), type);
if (result instanceof List) {
if (((List<?>) result).size() > 1) {
Comparator<Object> comparator = adaptDependencyComparator(matchingBeans);
// 排序
if (comparator != null) {
((List<?>) result).sort(comparator);
}
}
}
return result;
}
// 处理Map类型你
else if (Map.class == type) {
ResolvableType mapType = descriptor.getResolvableType().asMap();
Class<?> keyType = mapType.resolveGeneric(0);
if (String.class != keyType) {
return null;
}
Class<?> valueType = mapType.resolveGeneric(1);
if (valueType == null) {
return null;
}
// 查找候选者
Map<String, Object> matchingBeans = findAutowireCandidates(beanName, valueType,
new MultiElementDescriptor(descriptor));
if (matchingBeans.isEmpty()) {
return null;
}
if (autowiredBeanNames != null) {
autowiredBeanNames.addAll(matchingBeans.keySet());
}
return matchingBeans;
}
else {
return null;
}
}
findAutowireCandidates()
该方法用于发现用于注入的候选者。
// DefaultListableBeanFactory.java
protected Map<String, Object> findAutowireCandidates(
@Nullable String beanName, Class<?> requiredType, DependencyDescriptor descriptor) {
// 根据类型在BeanFactory以及祖先BeanFactory中查找到符合条件的Bean名称
String[] candidateNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this, requiredType, true, descriptor.isEager());
Map<String, Object> result = new LinkedHashMap<>(candidateNames.length);
// 第一,优先匹配可解析依赖的集合
for (Map.Entry<Class<?>, Object> classObjectEntry : this.resolvableDependencies.entrySet()) {
Class<?> autowiringType = classObjectEntry.getKey();
// 如果可解析依赖集合中的key和需要的类型匹配,也属于候选者
if (autowiringType.isAssignableFrom(requiredType)) {
Object autowiringValue = classObjectEntry.getValue();
// 解析依赖集合中的value,这里解析其实就是为了避免value是ObjectFactory类型,因为是这种类型的话,需要调用
// getObject()方法才能获取到真正的实例Bean对象
autowiringValue = AutowireUtils.resolveAutowiringValue(autowiringValue, requiredType);
// 将解析后的value与需要类型匹配,如果匹配,则添加到候选者集合中
if (requiredType.isInstance(autowiringValue)) {
result.put(ObjectUtils.identityToString(autowiringValue), autowiringValue);
break;
}
}
}
// 第二,处理在BeanFactory中找到出来的候选者名称
for (String candidate : candidateNames) {
// 如果不是自引用(即自己引用自己),并且是该候选者BeanDefinition中的isAutowireCandidate是true,也就是允许将
// 该Bean作为别的Bean实例的依赖,则也添加到候选者集合中
if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, descriptor)) {
addCandidateEntry(result, candidate, descriptor, requiredType);
}
}
// 如果前两步没有找到符合条件的候选者
if (result.isEmpty()) {
boolean multiple = indicatesMultipleBeans(requiredType);
// 如果还找不到任何候选者,请考虑后备匹配
DependencyDescriptor fallbackDescriptor = descriptor.forFallbackMatch();
for (String candidate : candidateNames) {
// 如果不是自引用,允许作为候选者,并且通过@Qualifier注解指定了名称的,也可以添加到候选者集合中
if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, fallbackDescriptor) &&
(!multiple || getAutowireCandidateResolver().hasQualifier(descriptor))) {
addCandidateEntry(result, candidate, descriptor, requiredType);
}
}
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;
}
determineAutowireCandidate()
如果有多个候选者,推断哪一个是最符合的候选者。
// DefaultListableBeanFactory.java
protected String determineAutowireCandidate(Map<String, Object> candidates, DependencyDescriptor descriptor) {
Class<?> requiredType = descriptor.getDependencyType();
// 添加了@Primary注解的优先级最高,如果存在多个,则报错
String primaryCandidate = determinePrimaryCandidate(candidates, requiredType);
if (primaryCandidate != null) {
return primaryCandidate;
}
// 如果没有@Primary注解,则比较@Priority,如果相同优先级的多个,则报错
String priorityCandidate = determineHighestPriorityCandidate(candidates, requiredType);
if (priorityCandidate != null) {
return priorityCandidate;
}
// 如果都没有,判断是否在可解析集合resolvableDependencies中或者候选者名称(以及别名)与需要注入的属性名是否一致
// 如果是,将该候选者作为最终的注入值
for (Map.Entry<String, Object> entry : candidates.entrySet()) {
String candidateName = entry.getKey();
Object beanInstance = entry.getValue();
if ((beanInstance != null && this.resolvableDependencies.containsValue(beanInstance)) ||
matchesBeanName(candidateName, descriptor.getDependencyName())) {
return candidateName;
}
}
return null;
}
至此,Spring依赖注入注解方式的源码就说完了,其中关于表达式解析或者类型转换的细节我们还没讲,这些内容后续会专门讲解。