前言
本文整理@Autowired注解背后源码处理机制
@Autowired
通过 @Autowired 注解注入 bean 的逻辑主要是通过 AutowiredAnnotationBeanPostProcessor bean-post-processor 实现
AutowiredAnnotationBeanPostProcessor
AutowiredAnnotationBeanPostProcessor 类图
从上图可以看出,AutowiredAnnotationBeanPostProcessor实现两个派系的接口;
1. 继承InstantiationAwareBeanPostProcessorAdapter 类,其覆盖InstantiationAwareBeanPostProcessor接口的方法postProcessPropertyValues;
InstantiationAwareBeanPostProcessorAdapter类对所有实现接口提供了默认的实现方法;
2. 实现MergedBeanDefinitionPostProcessor接口,该接口在 bean-post-processors 中被定义为 inner-bean-post-processors,实现其方法postProcessMergedBeanDefinition;
AutowiredAnnotationBeanPostProcessor#postProcessMergedBeanDefinition源码:
@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null);
metadata.checkConfigMembers(beanDefinition);
}
调用 findAutowiringMetadata 方法的分析在下文阐述;
调用流程总览
回顾Spring Beans 初始化流程分析中的 Do Get Bean 流程图,如下:
- 当AutowiredAnnotationBeanPostProcessor 作为接口MergedBeanDefinitionPostProcessor的实现时,其调用在step 1.3.1.1.3.3 applyMergedBeanDefinitionPostProcessors;该步骤主要是识别实例化后bean实例中被@Autowired注解的属性和方法并缓存;
- 当作为InstantiationAwareBeanPostProcessor接口的实现时,其调用在在 step 1.3.1.1.3.4.1 InstantiationAwareBeanPostProcessor 方法,该步骤主要是populate bean ;通过 @Autowired 注解所引用的对象给 bean 的属性赋值;
作为 inner-bean-post-processor实现
该行为对应流程图中的步骤是 step 1.3.1.1.3.3 applyMergedBeanDefinitionPostProcessors,一旦 bean instantiation 完毕,在 populate bean 之前,回调 inner-bean-post-processors;
该行为对应流程图中的步骤是 step 1.3.1.1.3.3 applyMergedBeanDefinitionPostProcessors,一旦 bean instantiation 完毕,在 populate bean 之前,回调 inner-bean-post-processors;
AbstractAutowireCapableBeanFactory.java
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)
throws BeanCreationException {
.....
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName); // 处理 internal-bean-post-processors
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing of merged bean definition failed", ex);
}
mbd.postProcessed = true;
}
}
....
}
可见,是直接通过调用 applyMergedBeanDefinitionPostProcessors 方法开始回调 inner-bean-post-processors 的;
AbstractAutowireCapableBeanFactory.java
/**
* Apply MergedBeanDefinitionPostProcessors to the specified bean definition,
* invoking their {@code postProcessMergedBeanDefinition} methods.
* @param mbd the merged bean definition for the bean
* @param beanType the actual type of the managed bean instance
* @param beanName the name of the bean
* @see MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition
*/
protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof MergedBeanDefinitionPostProcessor) {
MergedBeanDefinitionPostProcessor bdp = (MergedBeanDefinitionPostProcessor) bp;
bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName);
}
}
}
回调过程简单直接,直接获取当前 Spring Container 中所有已注册的 inner-bean-post-processors,然后依次回调 inner-bean-post-processors 的接口方法;这里想要补充的是,Spring 容器默认注册的 inner-bean-post-processors 有
- org.springframework.context.support.ApplicationContextAwareProcessor
- org.springframework.context.annotation.ConfigurationClassPostProcessor$ImportAwareBeanPostProcessor
- org.springframework.context.support.PostProcessorRegistrationDelegate$BeanPostProcessorChecker
- org.springframework.context.annotation.CommonAnnotationBeanPostProcessor
- org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor
- org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor
- org.springframework.context.support.ApplicationListenerDetector
AutowiredAnnotationBeanPostProcessor.java
@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
if (beanType != null) {
InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null);
metadata.checkConfigMembers(beanDefinition);
}
}
可见,通过调用 findAutowiringMetadata 方法返回一个 InjectionMetadata 类型的 metadata;
AutowiredAnnotationBeanPostProcessor#findAutowiringMetadata
private InjectionMetadata findAutowiringMetadata(String beanName, Class<?> clazz, @Nullable 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) {
//从缓存中找 InjectionMetadata,诸如 @Autowire,@Inject等
metadata = this.injectionMetadataCache.get(cacheKey);
// 如果找不到,则从这里开始,通过分析 bean,去找到它的 InjectionMetadata
if (InjectionMetadata.needsRefresh(metadata, clazz)) {
if (metadata != null) {
metadata.clear(pvs);
}
// 去找,并构建其 InjectionMetadata 对象
metadata = buildAutowiringMetadata(clazz);
// 如果找到了,将其放入 injectionMetadataCache 中返回;
this.injectionMetadataCache.put(cacheKey, metadata);
}
}
}
return metadata;
}
以上源码主要是先从缓存中找是否已经有该 InjectionMetadata 存在了?如有,且无需进行 refresh,则返回;如果在缓存中不存在(或者存在且需要 refresh),那么就需要去构建一个 InjectionMetadata 类型的 AutowiringMetadata;
最重要的是buildAutowiringMetadata(clazz)方法,再来看看
AutowiredAnnotationBeanPostProcessor#buildAutowiringMetadata
private InjectionMetadata buildAutowiringMetadata(final Class<?> clazz) {
LinkedList<InjectionMetadata.InjectedElement> elements = new LinkedList<>();
Class<?> targetClass = clazz;
do {
final LinkedList<InjectionMetadata.InjectedElement> currElements = new LinkedList<>();
// 1. 通过反射从 targetClass 的 field 中去找 annotation
ReflectionUtils.doWithLocalFields(targetClass, field -> {
// 是否存在 @Autowired
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));
}
});
// 2. 通过反射从 targetClass 的 method 中去找 annotation
ReflectionUtils.doWithLocalMethods(targetClass, method -> {
// 处理 bridged method 相关情况;
Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
if (!BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) {
return;
}
AnnotationAttributes ann = findAutowiredAnnotation(bridgedMethod);
// 是否存在 @Autowired
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.getParameterCount() == 0) {
if (logger.isWarnEnabled()) {
logger.warn("Autowired annotation should only 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);
}
该方法分为两部分,通过工具类 ReflectionUtils 分别从当前 bean 实例 fields 和 methods 中去查找@Autowired注解;
- 从 fields 找@Autowired注解;若找到,则创建AutowiredFieldElement实例,并放入 currElements 队列中
- 从 methods 中找@Autowired注解;若找到,则创建AutowiredMethodElement实例,并放入 currElements 队列中
- 最后,通过 bean 的 Class 对象 和 curreElements 构建InjectionMetadata实例并返回;
最后回到 AutowiredAnnotationBeanPostProcessor#findAutowiringMetadata 方法中,将刚才生成并返回的 InjectionMetadata 注入缓存 injectionMetadataCache 中,返回;
通过上述的一系列步骤,可以看到,当AutowiredAnnotationBeanPostProcessor作为 inner-bean-post-processor 的时候,从当前 instantiated bean 的属性和方法中解析出了@Autowired注解属性,并将其通过 injectionMetadataCache 缓存到了当前的FactoryBean中;
作为 InstantiationAwareBeanPostProcessor 的行为
该步骤是发生在 step 1.3.1.1.3.4.1: 回调 InstantiationAwareBeanPostProcessor 接口方法
AbstractAutowireCapableBeanFactory#populateBean
if (hasInstAwareBpps || needsDepCheck) {
PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
if (hasInstAwareBpps) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvs == null) {
return;
}
}
}
}
if (needsDepCheck) {
checkDependencies(beanName, mbd, filteredPds, pvs);
}
}
AutowiredAnnotationBeanPostProcessor#postProcessPropertyValues
@Override
public PropertyValues postProcessPropertyValues(
PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeanCreationException {
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;
}
重点是 metadata.inject(bean, beanName, pvs);
InjectionMetadata#inject
public void inject(Object target, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
Collection<InjectedElement> checkedElements = this.checkedElements;
Collection<InjectedElement> elementsToIterate =
(checkedElements != null ? 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);
}
}
}
InjectionMetadata对象本身是一个包含了一系列AutowiredFieldElement和AutowiredMethodElement对象的队列所构成;这里通过迭代InjectedElement依次处理AutowiredFieldElement或AutowiredMethodElement元素
注意,InjectedElement 是 AutowiredFieldElement 和 AutowiredMethodElement 的超类,所以,接下来的流程会分为两种情况
1.AutowiredFieldElement#inject(Object bean, String beanName, PropertyValues pvs)
@Override
protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
Field field = (Field) this.member;
Object value;
if (this.cached) {
// 如果该 @Autowired ref bean 已经被解析过,直接从缓存中获取;
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 {
// 1. 解析出 @Autowired 所 annotated 的实例
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();
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) {
// 如果该属性是 private 的,那么 make accessiable
ReflectionUtils.makeAccessible(field);
//通过反射将 @Autowired annotated ref-bean 写入当前 bean 的属性中
field.set(bean, value);
}
}
其实重点就是做了两件事情:首先,解析 @Autowired 所标注的 ref bean;然后,将该 ref bean 通过 field 注入当前的 bean
这里最重要的beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);解析ref bean,接下来再深入看看;
2. AutowiredMethodElement#inject
该方法与 #1 非常类似
解析 ref bean 流程
DefaultListableBeanFactory#resolveDependency
public Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName,
@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {
descriptor.initParameterNameDiscovery(getParameterNameDiscoverer());
if (Optional.class == descriptor.getDependencyType()) {
return createOptionalDependency(descriptor, requestingBeanName);
}
else if (ObjectFactory.class == descriptor.getDependencyType() ||
ObjectProvider.class == descriptor.getDependencyType()) {
return new DependencyObjectProvider(descriptor, requestingBeanName);
}
else if (javaxInjectProviderClass == descriptor.getDependencyType()) {
return new Jsr330ProviderFactory().createDependencyProvider(descriptor, requestingBeanName);
}
else {
// 返回该 lazy proxy 表示延迟初始化,实现过程是查看在 @Autowired 注解处是否使用了 @Lazy = true 注解
Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(
descriptor, requestingBeanName);
if (result == null) {
// 大部分的通过 @Autowired 注解的普通 bean 将会在这里进行初始化
result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
}
return result;
}
}
这里的解析过程根据 @Autowired 所 ref bean 的类型,分为了四种情况进行处理
- java.Util.Optional Class 类型
- ObjectFactory 或者 ObjectProvider 类型
- javaxInjectProviderClass 既是 JSR330 类型
- 普通的 ref bean
下面根据第4种情况的主线流程继续分析
DefaultListableBeanFactory#doResolveDependency
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();
Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);
//默认实现返回null
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()));
}
//处理数组、List、Map等类型
Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
if (multipleBeans != null) {
return multipleBeans;
}
//1. 根据 type 去找到对应的 candidates,该方法内部会处理 @Qualifier 的情况
Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
if (matchingBeans.isEmpty()) {
if (isRequired(descriptor)) {
raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
}
return null;
}
String autowiredBeanName;
Object instanceCandidate;
if (matchingBeans.size() > 1) {
//2. 根据 @Primary and @Priority 注解进行筛选
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;
}
}
instanceCandidate = matchingBeans.get(autowiredBeanName);
}
else {
// We have exactly one match.
Map.Entry<String, Object> entry = matchingBeans.entrySet().iterator().next();
autowiredBeanName = entry.getKey();
instanceCandidate = entry.getValue();// 这里返回的是 Class Type
}
if (autowiredBeanNames != null) {
autowiredBeanNames.add(autowiredBeanName);
}
if (instanceCandidate instanceof Class) {
// 3.这个方法会调用 Factory.getBean.. 去实例化找到的 Class Type
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);
}
}
这段代码的主流程主要做了以下三件事情
- 据 Class Type 去找到对应的 candidates,见代码第 14 行;备注,该方法内部会处理 @Qualifier 的情况,具体分析过程参考通过 Class Type 寻找 Candidates;
- 如果返回的 candidates 有多个,再根据 @Primary and @Priority 注解进行筛选
- 最后初始化 candiate 并返回
DependencyDescriptor#resolveCandidate
public Object resolveCandidate(String beanName, Class<?> requiredType, BeanFactory beanFactory)
throws BeansException {
return beanFactory.getBean(beanName);
}
可以看到,通过 Do Get Bean 流程初始化对应的 candidate;
通过 Class Type 以及 @Qualifer 寻找 Candidates
DefaultListableBeanFactory#findAutowireCandidates
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 = new LinkedHashMap<>(candidateNames.length);
// 1. 依次从所有已经解析的 Type 去找是否已经存在对应的 Type 了?如果有,则添加对应 Type 的 bean 实例到 result 队里当中;注意,如果找到了,这里加入 result 的就不再是 Class Type 了,而是 instance
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 candidate : candidateNames) {
// 2. isAutowireCandidate(candidate, descriptor) 会去判断 @Qualifier 逻辑
if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, descriptor)) {
addCandidateEntry(result, candidate, descriptor, requiredType);
}
}
if (result.isEmpty() && !indicatesMultipleBeans(requiredType)) {
// Consider fallback matches if the first pass failed to find anything...
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.
for (String candidate : candidateNames) {
if (isSelfReference(beanName, candidate) &&
(!(descriptor instanceof MultiElementDescriptor) || !beanName.equals(candidate)) &&
isAutowireCandidate(candidate, fallbackDescriptor)) {
addCandidateEntry(result, candidate, descriptor, requiredType);
}
}
}
}
return result;
}
从该方法的注解中可以知道,就是通过 required type (既是 @Autowired 注解的需要被注入的实例的 Class Type) 去查找 Spring 容器中的 candidates;这里需要注意的是它的几个参数
- beanName <String> 当前 bean
- requiredType <Class<?> > @Autowired 注解的需要被注入的 ref 的 Class Type
- descriptor <DependencyDescriptor> DependencyDescriptor 一个简单的 POJO 对象,用来保存当前 Dependency 的一些当前状态
这段代码的代码主要做了两件事情:
- 从缓存中找该 requiredType 是否已经被成功解析过,若是,则直接返回缓存中已经解析好的实例;注意,这里是该方法比较特殊的地方,它通过返回类型 Object 既可以返回 candidate Class Type,也可以返回 candidate instance;
- 若在缓存中没有找到,它会依次从当前的 candidates 中去查找是否是最终符合的 candidate,如果是符合的 candidate,将会加入 result;
下面就isAutowireCandidate的寻找过程做进一步的分析
@Override
public boolean isAutowireCandidate(String beanName, DependencyDescriptor descriptor)
throws NoSuchBeanDefinitionException {
return isAutowireCandidate(beanName, descriptor, getAutowireCandidateResolver());
}
getAutowireCandidateResolver() 返回 ContextAnnotationAutowireCandidateResolver
DefaultListableBeanFactory.java
protected boolean isAutowireCandidate(String beanName, DependencyDescriptor descriptor, AutowireCandidateResolver resolver)
throws NoSuchBeanDefinitionException {
String beanDefinitionName = BeanFactoryUtils.transformedBeanName(beanName);
if (containsBeanDefinition(beanDefinitionName)) {
// 该方法的内部流程中会去判断 @Qualifier 逻辑
return isAutowireCandidate(beanName, getMergedLocalBeanDefinition(beanDefinitionName), descriptor, resolver);
}
else if (containsSingleton(beanName)) {
// 该方法的内部流程中会去判断 @Qualifier 逻辑
return isAutowireCandidate(beanName, new RootBeanDefinition(getType(beanName)), descriptor, resolver);
}
// 如果在当前的 BeanFactory 中没有找到,将会继续从 Parent BeanFactory 中查找
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;
}
}
该方法主要包含两部分逻辑
- 从当前的 FactoryBean 中查找,有两个分支流程,不过最终都是调用的 isAutowireCandidate 方法来判断是否是 Autowired 所需要的 ref bean;
- 若 #1 没有找到,则从其 Parent Factory Bean 中查找;
下面就 isAutowireCandidate 方法继续进行分析
protected boolean isAutowireCandidate(String beanName, RootBeanDefinition mbd,
DependencyDescriptor descriptor, AutowireCandidateResolver resolver) {
String beanDefinitionName = BeanFactoryUtils.transformedBeanName(beanName);
// 解析 bean name 对应的 ClassType,并且将解析后的 ClassType 缓存到 bean definitions 中;
resolveBeanClass(mbd, beanDefinitionName);
if (mbd.isFactoryMethodUnique) {
boolean resolve;
synchronized (mbd.constructorArgumentLock) {
resolve = (mbd.resolvedConstructorOrFactoryMethod == null);
}
if (resolve) {
new ConstructorResolver(this).resolveFactoryMethodIfPossible(mbd);
}
}
return resolver.isAutowireCandidate(
new BeanDefinitionHolder(mbd, beanName, getAliases(beanDefinitionName)), descriptor);
}
QualifierAnnotationAutowireCandidateResolver.java
@Override
public boolean isAutowireCandidate(BeanDefinitionHolder bdHolder, DependencyDescriptor descriptor) {
boolean match = super.isAutowireCandidate(bdHolder, descriptor);
if (match) {
// 1. 在这里判断的 Qualifier;如果当前的 descriptor 中有标注 @Qualifier,那么 bean 必须与之匹配,才可以返回;
match = checkQualifiers(bdHolder, descriptor.getAnnotations());
if (match) {
// 2. 继续匹配 method 参数..
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;
}
这里分别对属性和方法进行了匹配,首先对属性进行匹配,然后对方法进行匹配;这里分析第一种情况
QualifierAnnotationAutowireCandidateResolver#checkQualifiers
protected boolean checkQualifiers(BeanDefinitionHolder bdHolder, Annotation[] annotationsToSearch) {
if (ObjectUtils.isEmpty(annotationsToSearch)) {
return true;
}
SimpleTypeConverter typeConverter = new SimpleTypeConverter();
for (Annotation annotation : annotationsToSearch) {
Class<? extends Annotation> type = annotation.annotationType();
boolean checkMeta = true;
boolean fallbackToMeta = false;
// 判断当前的注解是不是 @Qualifier
if (isQualifier(type)) {
//1. 深度的根据 @Qualifier 中定义的 name 与当前 ref-bean 进行匹配 ..
if (!checkQualifier(bdHolder, annotation, typeConverter)) {
fallbackToMeta = true;
}
else {
checkMeta = false;
}
}
// 2. 从 meta annoation 中查找;
if (checkMeta) {
boolean foundMeta = false;
for (Annotation metaAnn : type.getAnnotations()) {
Class<? extends Annotation> metaType = metaAnn.annotationType();
if (isQualifier(metaType)) {
foundMeta = true;
// Only accept fallback match if @Qualifier annotation has a value...
// Otherwise it is just a marker for a custom qualifier annotation.
if ((fallbackToMeta && StringUtils.isEmpty(AnnotationUtils.getValue(metaAnn))) ||
!checkQualifier(bdHolder, metaAnn, typeConverter)) {
return false;
}
}
}
if (fallbackToMeta && !foundMeta) {
return false;
}
}
}
return true;
}
这里处理 annotation 分为两个分支
- 分支 1, 处理 @Qualifier;
- 分支 2, 处理 meta annotation;
这里重点关注与当前主流程相关的分支 1,既当当前的注解是 @Qualifier 的处理流程
protected boolean checkQualifier(
BeanDefinitionHolder bdHolder, Annotation annotation, TypeConverter typeConverter) {
Class<? extends Annotation> type = annotation.annotationType();
RootBeanDefinition bd = (RootBeanDefinition) bdHolder.getBeanDefinition();
// 一、从 Target Class 中找匹配的 @Qualifier
// 首先,从 Target-class 中查找,是否有对应的注解 @Qualifier,使用全名查找 org.springframework.beans.factory.annotation.Qualifier
AutowireCandidateQualifier qualifier = bd.getQualifier(type.getName());
if (qualifier == null) {
// 其次,逻辑基本上和上面一样,只是这里使用的是 Qualifier 的 short name: 既 Qualifier,这里所考虑到的一种情况是,万一使用的不是 spring 的 Qualifier Annotation,而是用户自定义的 @Qualifier,那么这里这样处理可以兼容之;
qualifier = bd.getQualifier(ClassUtils.getShortName(type));
}
// 如果通过上面两个步骤依然找不到 @Qualifier,则试图从 Factory Method、BeanFactory 中去找...
if (qualifier == null) {
// First, check annotation on qualified element, if any
Annotation targetAnnotation = getQualifiedElementAnnotation(bd, type);
// Then, check annotation on factory method, if applicable
if (targetAnnotation == null) {
targetAnnotation = getFactoryMethodAnnotation(bd, type);
}
if (targetAnnotation == null) {
RootBeanDefinition dbd = getResolvedDecoratedDefinition(bd);
if (dbd != null) {
targetAnnotation = getFactoryMethodAnnotation(dbd, type);
}
}
if (targetAnnotation == null) {
// Look for matching annotation on the target class
if (getBeanFactory() != null) {
try {
Class<?> beanType = getBeanFactory().getType(bdHolder.getBeanName());
if (beanType != null) {
targetAnnotation = AnnotationUtils.getAnnotation(ClassUtils.getUserClass(beanType), type);
}
}
catch (NoSuchBeanDefinitionException ex) {
// Not the usual case - simply forget about the type check...
}
}
if (targetAnnotation == null && bd.hasBeanClass()) {
targetAnnotation = AnnotationUtils.getAnnotation(ClassUtils.getUserClass(bd.getBeanClass()), type);
}
}
if (targetAnnotation != null && targetAnnotation.equals(annotation)) {
return true;
}
}
// 二、匹配过程正式开始,
// 深度匹配正式拉开序幕,开始依次深度剖析 Annotation 中的 Attributes
Map<String, Object> attributes = AnnotationUtils.getAnnotationAttributes(annotation);
if (attributes.isEmpty() && qualifier == null) {
// If no attributes, the qualifier must be present
return false;
}
for (Map.Entry<String, Object> entry : attributes.entrySet()) {
String attributeName = entry.getKey();
Object expectedValue = entry.getValue();
Object actualValue = null; // 保存 target-class 中的 @Qualifier value 的实际值
// Check qualifier first 从当前的 target-class 对象去找 @Qualifier 对应的值
if (qualifier != null) {
actualValue = qualifier.getAttribute(attributeName);
}
if (actualValue == null) {
// Fall back on bean definition attribute 从 xml bean configuration 中找 <qualifier> 元素的定义的值
actualValue = bd.getAttribute(attributeName);
}
//重要的就是 bdHolder.matchesName((String) expectedValue) 方法,比对 target 的 beanname 与 aliasname 是否与 @Qualifier 中的 value 值相匹配
if (actualValue == null && attributeName.equals(AutowireCandidateQualifier.VALUE_KEY) &&
expectedValue instanceof String && bdHolder.matchesName((String) expectedValue)) {
// Fall back on bean name (or alias) match 里回溯至使用 target 的 bean name 或者是 alias name 的与 @Qualifier 的 value 的匹配方式了
continue;
}
if (actualValue == null && qualifier != null) {
// Fall back on default, but only if the qualifier is present
actualValue = AnnotationUtils.getDefaultValue(annotation, attributeName);
}
if (actualValue != null) {
actualValue = typeConverter.convertIfNecessary(actualValue, expectedValue.getClass());
}
if (!expectedValue.equals(actualValue)) {
return false;
}
}
return true;
}
上述代码的逻辑主要分为两个部分
- 从 target class 中去找与当前 bean 所匹配的 @Qualifier
- 根据@Qualifier来匹配适合的 candidate
使用一个循环分别来匹配 @Qualifier 中的所有键值对
为什么使用一个循环来匹配 @Qualifier 中的所有属性值,而且必须是全部匹配,如果有一个属性不匹配,则返回 false
主要是为了应对自定义 @Qualifier 并且包含多个键值对的情况 **
要求target-class 中的 @Qualifier 必须全匹配,匹配其中所有的键值对才算成功匹配;
总结
可见,@Autowired 主要是根据 Class Type 去匹配 candidates,如果有多个 candidates,只有当 @Qualifier 匹配失败以后,才会 fall back 至使用 bean name 的方式进行匹配,这也是为什么 Spring 官方文档中明确说明的,如果是期望用 bean name 的方式来匹配 target bean,不建议使用 @Autowired,而建议使用 @Resource,因为 @Resource 本身的实现逻辑就是使用 bean name 的方式来进行匹配的;
@Resource 注解需要引用 javax.annoation-api.jar;最后,如果当 @Resource 没有通过名字找到对应的 candidate,将会 fall back to @Autowired 的查找逻辑;
注入 ApplicationContext
通过 @Autowired 注入接口 BeanFactory, ApplicationContext, Environment, ResourceLoader, ApplicationEventPublisher, 和 MessageSource 以及注入他们的扩展接口ConfigurableApplicationContext和ResourcePatternResolver 等;
整个流程和通过 @Autowired 注解注入普通 bean 非常类同,从解析 ref bean 流程到通过 Class Type 以及 @Qualifer 寻找 Candidates 流程之间的步骤都相同,唯一的区别是当进入通过 Class Type 以及 @Qualifer 寻找 Candidates 流程以后;
DefaultListableBeanFactory#findAutowireCandidates
protected Map<String, Object> findAutowireCandidates(
String beanName, Class<?> requiredType, DependencyDescriptor descriptor) {
String[] candidateNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this, requiredType, true, descriptor.isEager()); // 返回 niba 和 kiba
Map<String, Object> result = new LinkedHashMap<String, Object>(candidateNames.length);
// 1. 依次从所有已经解析的 Type 去找是否已经存在对应的 Type 了?如果有,则添加对应 Type 的 bean 实例到 result 队里当中;注意,如果找到了,这里加入 result 的就不再是 Class Type 了,而是 instance
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 candidate : candidateNames) {
// 2. isAutowireCandidate(candidate, descriptor) 会去判断 @Qualifier 逻辑
if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, descriptor)) {
// 根据 candidate 的名字找到其对应的 Type,返回并添加入 result, 比如得到 niba = class org.shangyang.spring.container.Dog
addCandidateEntry(result, candidate, descriptor, requiredType);
}
}
....
return result;
}
通过 @Autowired 注入的普通 bean 走的是第二个流程,而这里,走的是第一个流程,既是从缓存 (this.resolvableDependencies) 中去找,找到当前容器 bean ApplicaitonContext既返回;
在容器启动以后,在当前的 default BeanFactory 中通过 resolvableDependencies 缓存了如下的键值对(假设Spring容器从类路径加载配置文件)
键 | 值 |
---|---|
interface org.springframework.core.io.ResourceLoader | org.springframework.context.support.ClassPathXmlApplicationContext |
interface org.springframework.context.ApplicationContext | org.springframework.context.support.ClassPathXmlApplicationContext |
interface org.springframework.context.ApplicationEventPublisher | org.springframework.context.support.ClassPathXmlApplicationContext |
interface org.springframework.beans.factory.BeanFactory | org.springframework.beans.factory.support.DefaultListableBeanFactory |
注册源码:
AbstractApplicationContext
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// Tell the internal bean factory to use the context's class loader etc.
beanFactory.setBeanClassLoader(getClassLoader());
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
// Configure the bean factory with context callbacks.
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
// BeanFactory interface not registered as resolvable type in a plain factory.
// MessageSource registered (and found for autowiring) as a bean.
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);
// Register early post-processor for detecting inner beans as ApplicationListeners.
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
// Detect a LoadTimeWeaver and prepare for weaving, if found.
if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
// Set a temporary ClassLoader for type matching.
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
// Register default environment beans.
if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
}
if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
}
if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
}
}
DefaultListableBeanFactory#registerResolvableDependency
@Override
public void registerResolvableDependency(Class<?> dependencyType, @Nullable Object autowiredValue) {
Assert.notNull(dependencyType, "Dependency type must not be null");
if (autowiredValue != null) {
if (!(autowiredValue instanceof ObjectFactory || dependencyType.isInstance(autowiredValue))) {
throw new IllegalArgumentException("Value [" + autowiredValue +
"] does not implement specified dependency type [" + dependencyType.getName() + "]");
}
this.resolvableDependencies.put(dependencyType, autowiredValue);
}
}
http://www.shangyang.me/2017/04/05/spring-core-container-sourcecode-analysis-annotation-autowired/