AutowiredAnnotationBeanPostProcessor是一个Bean后置处理器,用于处理@Autowired @value的 注入。
1、@Autowired可添加在属性上,通过Spring自动注入属性值
2、@Autowired可添加构造方法,通过Spring容器在创建过程中通过调用BeanPostProcessor的实现子类的determineCandidateConstructors方法,进行构造函数的筛选,确定应该使用的构造函数,对存在多个有参构造函数时,将不指定构造函数使用的范围,交由Spring通过自己的算法进行判断。
3、@Autowired可添加方法上(名字可以随便起,所以并不一定是set方法,普通方法也行),通过Spring自动设置方法参数的值
4、@Value ,通过@value中设置的参数进行注入
5、@Lookup,识别类与父类的添加了@Lookup的抽象方法,并添加到缓存
lookupMethodsChecked中,用作后续的处理
.....
下面是图片,在这里会持续完善
下面是整个类加了注释的源码
/*
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.beans.factory.annotation;
import java.beans.PropertyDescriptor;
import java.lang.annotation.Annotation;
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.PropertyValues;
import org.springframework.beans.TypeConverter;
import org.springframework.beans.factory.BeanCreationException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.BeanFactoryUtils;
import org.springframework.beans.factory.InjectionPoint;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.UnsatisfiedDependencyException;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.config.DependencyDescriptor;
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessorAdapter;
import org.springframework.beans.factory.support.LookupOverride;
import org.springframework.beans.factory.support.MergedBeanDefinitionPostProcessor;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.core.BridgeMethodResolver;
import org.springframework.core.MethodParameter;
import org.springframework.core.Ordered;
import org.springframework.core.PriorityOrdered;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.core.annotation.MergedAnnotation;
import org.springframework.core.annotation.MergedAnnotations;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.ReflectionUtils;
import org.springframework.util.StringUtils;
/**
* {@link org.springframework.beans.factory.config.BeanPostProcessor BeanPostProcessor}
* implementation that autowires annotated fields, setter methods, and arbitrary
* config methods. Such members to be injected are detected through annotations:
* by default, Spring's {@link Autowired @Autowired} and {@link Value @Value}
* annotations.
*
* Also supports JSR-330's {@link javax.inject.Inject @Inject} annotation,
* if available, as a direct alternative to Spring's own {@code @Autowired}.
*
*
Autowired Constructors
* Only one constructor of any given bean class may declare this annotation with
* the 'required' attribute set to {@code true}, indicating the constructor
* to autowire when used as a Spring bean. Furthermore, if the 'required' attribute
* is set to {@code true}, only a single constructor may be annotated with
* {@code @Autowired}. If multiple non-required constructors declare the
* annotation, they will be considered as candidates for autowiring. The constructor
* with the greatest number of dependencies that can be satisfied by matching beans
* in the Spring container will be chosen. If none of the candidates can be satisfied,
* then a primary/default constructor (if present) will be used. If a class only
* declares a single constructor to begin with, it will always be used, even if not
* annotated. An annotated constructor does not have to be public.
*
*
Autowired Fields
* Fields are injected right after construction of a bean, before any
* config methods are invoked. Such a config field does not have to be public.
*
*
Autowired Methods
* Config methods may have an arbitrary name and any number of arguments; each of
* those arguments will be autowired with a matching bean in the Spring container.
* Bean property setter methods are effectively just a special case of such a
* general config method. Config methods do not have to be public.
*
*
Annotation Config vs. XML Config
* A default {@code AutowiredAnnotationBeanPostProcessor} will be registered
* by the "context:annotation-config" and "context:component-scan" XML tags.
* Remove or turn off the default annotation configuration there if you intend
* to specify a custom {@code AutowiredAnnotationBeanPostProcessor} bean definition.
*
*
NOTE: Annotation injection will be performed before XML injection;
* thus the latter configuration will override the former for properties wired through
* both approaches.
*
*
{@literal @}Lookup Methods
* In addition to regular injection points as discussed above, this post-processor
* also handles Spring's {@link Lookup @Lookup} annotation which identifies lookup
* methods to be replaced by the container at runtime. This is essentially a type-safe
* version of {@code getBean(Class, args)} and {@code getBean(String, args)}.
* See {@link Lookup @Lookup's javadoc} for details.
*
* @author Juergen Hoeller
* @author Mark Fisher
* @author Stephane Nicoll
* @author Sebastien Deleuze
* @author Sam Brannen
* @since 2.5
* @see #setAutowiredAnnotationType
* @see Autowired
* @see Value
*/
public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter
implements MergedBeanDefinitionPostProcessor, PriorityOrdered, BeanFactoryAware {
protected final Log logger = LogFactory.getLog(getClass());
// 该处理器支持解析的注解们,默认支持的是3个
private final Set> autowiredAnnotationTypes = new LinkedHashSet<>(4);
// @Autowired(required = false)这个注解的属性值名称
private String requiredParameterName = "required";
// 这个值一般请不要改变(若改成false,效果required = false的作用是相反的了)
private boolean requiredParameterValue = true;
private int order = Ordered.LOWEST_PRECEDENCE - 2;
@Nullable
private ConfigurableListableBeanFactory beanFactory;
// 对@Lookup方法的支持
private final Set lookupMethodsChecked = Collections.newSetFromMap(new ConcurrentHashMap<>(256));
// 构造函数候选器缓存
private final Map, Constructor>[]> candidateConstructorsCache = new ConcurrentHashMap<>(256);
// 方法注入、字段filed注入
// 此处InjectionMetadata这个类非常重要,到了此处@Autowired注解含义已经没有了,完全被准备成这个元数据了
// InjectionMetadata持有targetClass、Collection injectedElements等两个重要属性
// 其中InjectedElement这个抽象类最重要的两个实现为:AutowiredFieldElement和AutowiredMethodElement
private final Map injectionMetadataCache = new ConcurrentHashMap<>(256);
/**
* 构造方法,完成对应注解的注入
*
* Create a new {@code AutowiredAnnotationBeanPostProcessor} for Spring's
* standard {@link Autowired @Autowired} and {@link Value @Value} annotations.
* Also supports JSR-330's {@link javax.inject.Inject @Inject} annotation,
* if available.
*/
@SuppressWarnings("unchecked")
public AutowiredAnnotationBeanPostProcessor() {
this.autowiredAnnotationTypes.add(Autowired.class);
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.
}
}
/**
* 自定义支持的依赖注入注解类型
*
* Set the 'autowired' annotation type, to be used on constructors, fields,
* setter methods, and arbitrary config methods.
*
The default autowired annotation types are the Spring-provided
* {@link Autowired @Autowired} and {@link Value @Value} annotations as well
* as JSR-330's {@link javax.inject.Inject @Inject} annotation, if available.
*
This setter property exists so that developers can provide their own
* (non-Spring-specific) annotation type to indicate that a member is supposed
* to be autowired.
*/
public void setAutowiredAnnotationType(Class extends Annotation> autowiredAnnotationType) {
Assert.notNull(autowiredAnnotationType, "'autowiredAnnotationType' must not be null");
this.autowiredAnnotationTypes.clear();
this.autowiredAnnotationTypes.add(autowiredAnnotationType);
}
/**
* Set the 'autowired' annotation types, to be used on constructors, fields,
* setter methods, and arbitrary config methods.
*
The default autowired annotation types are the Spring-provided
* {@link Autowired @Autowired} and {@link Value @Value} annotations as well
* as JSR-330's {@link javax.inject.Inject @Inject} annotation, if available.
*
This setter property exists so that developers can provide their own
* (non-Spring-specific) annotation types to indicate that a member is supposed
* to be autowired.
*/
public void setAutowiredAnnotationTypes(Set> autowiredAnnotationTypes) {
Assert.notEmpty(autowiredAnnotationTypes, "'autowiredAnnotationTypes' must not be empty");
this.autowiredAnnotationTypes.clear();
this.autowiredAnnotationTypes.addAll(autowiredAnnotationTypes);
}
/**
* Set the name of an attribute of the annotation that specifies whether it is required.
* @see #setRequiredParameterValue(boolean)
*/
public void setRequiredParameterName(String requiredParameterName) {
this.requiredParameterName = requiredParameterName;
}
/**
* Set the boolean value that marks a dependency as required.
* For example if using 'required=true' (the default), this value should be
* {@code true}; but if using 'optional=false', this value should be {@code false}.
* @see #setRequiredParameterName(String)
*/
public void setRequiredParameterValue(boolean requiredParameterValue) {
this.requiredParameterValue = requiredParameterValue;
}
public void setOrder(int order) {
this.order = order;
}
@Override
public int getOrder() {
return this.order;
}
// bean工厂必须是ConfigurableListableBeanFactory的
@Override
public void setBeanFactory(BeanFactory beanFactory) {
if (!(beanFactory instanceof ConfigurableListableBeanFactory)) {
throw new IllegalArgumentException(
"AutowiredAnnotationBeanPostProcessor requires a ConfigurableListableBeanFactory: " + beanFactory);
}
this.beanFactory = (ConfigurableListableBeanFactory) beanFactory;
}
/**
* 处理合并的bean定义信息
* 1、解析@Autowired等注解然后转换
* 2、把注解信息转换为InjectionMetadata然后缓存到上面的injectionMetadataCache里面
* @param beanDefinition the merged bean definition for the bean
* @param beanType the actual type of the managed bean instance
* @param beanName the name of the bean
*/
@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class> beanType, String beanName) {
// 解析注解并缓存
InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null);
metadata.checkConfigMembers(beanDefinition);
}
@Override
public void resetBeanDefinition(String beanName) {
this.lookupMethodsChecked.remove(beanName);
this.injectionMetadataCache.remove(beanName);
}
/**
* 获取构造器集合
* 如果有多个Autowired,required为true,不管有没有默认构造方法,会报异常
* 如果只有一个Autowired,required为false,没有默认构造方法,会报警告
* 如果没有Autowired注解,定义了两个及以上有参数的构造方法,没有无参构造方法,
* 其他情况都可以,但是以有Autowired的构造方法优先,然后才是默认构造方法
*
*
* @param beanClass
* @param beanName
* @return
* @throws BeanCreationException
*/
@Override
@Nullable
public Constructor>[] determineCandidateConstructors(Class> beanClass, final String beanName)
throws BeanCreationException {
// Let's check for lookup methods here...
// 处理包含@Loopup注解的方法,如果集合中没有beanName,则走一遍bean中的所有方法,过滤是否含有lookup方法
if (!this.lookupMethodsChecked.contains(beanName)) {
if (AnnotationUtils.isCandidateClass(beanClass, Lookup.class)) {
try {
Class> targetClass = beanClass;
do {
// 遍历当前类以及所有父类,找出lookup注解的方法进行处理
ReflectionUtils.doWithLocalMethods(targetClass, method -> {
// 获取method上的Lookup注解
Lookup lookup = method.getAnnotation(Lookup.class);
// 存在此注解的话,就将方法和注解中的内容构建LookupOverride对象,设置进BeanDefinition中
if (lookup != null) {
Assert.state(this.beanFactory != null, "No BeanFactory available");
LookupOverride override = new LookupOverride(method, lookup.value());
try {
RootBeanDefinition mbd = (RootBeanDefinition)
this.beanFactory.getMergedBeanDefinition(beanName);
mbd.getMethodOverrides().addOverride(override);
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(beanName,
"Cannot apply @Lookup to beans without corresponding bean definition");
}
}
});
targetClass = targetClass.getSuperclass();
}
//遍历父类,直到Object
while (targetClass != null && targetClass != Object.class);
}
catch (IllegalStateException ex) {
throw new BeanCreationException(beanName, "Lookup method resolution failed", ex);
}
}
// 无论对象中是否含有@Lookup方法,过滤完成后都会放到集合中,证明此bean已经检查完@Lookup注解
this.lookupMethodsChecked.add(beanName);
}
// Quick check on the concurrent map first, with minimal locking.
// 从缓存中拿构造函数,不存在的话就进入代码块中再拿一遍,还不存在的话就进行下方的逻辑,
Constructor>[] candidateConstructors = this.candidateConstructorsCache.get(beanClass);
// 没找到再同步
if (candidateConstructors == null) {
// Fully synchronized resolution now...
synchronized (this.candidateConstructorsCache) {
//再检测一遍,双重检测
candidateConstructors = this.candidateConstructorsCache.get(beanClass);
if (candidateConstructors == null) {
Constructor>[] rawCandidates;
try {
//获取bean中所有的构造函数
rawCandidates = beanClass.getDeclaredConstructors();
}
catch (Throwable ex) {
throw new BeanCreationException(beanName,
"Resolution of declared constructors on bean Class [" + beanClass.getName() +
"] from ClassLoader [" + beanClass.getClassLoader() + "] failed", ex);
}
// 暂时候选构造函数集合,
List> candidates = new ArrayList<>(rawCandidates.length);
// 带有依赖项的构造函数
Constructor> requiredConstructor = null;
// 默认使用的构造函数
Constructor> defaultConstructor = null;
// 获取主构造函数
Constructor> primaryConstructor = BeanUtils.findPrimaryConstructor(beanClass);
// 标识,表示不是合成构造函数的数量
// 合成构造函数->有方法参数并对实例进行赋值的构造函数
int nonSyntheticConstructors = 0;
// 遍历所有的构造函数
for (Constructor> candidate : rawCandidates) {
// 构造函数不是合成构造函数,标识累加
if (!candidate.isSynthetic()) {
nonSyntheticConstructors++;
}
else if (primaryConstructor != null) {
continue;
}
// 查找构造函数上@Autowired注解的属性,
MergedAnnotation> ann = findAutowiredAnnotation(candidate);
// 注解不存在,则再通过方法获取用户类,如果是用户类则返回用户类,还判断了cglib的情况,cglib情况则返回目标类
// 然后获取参数一致的构造函数再获取注解
if (ann == null) {
Class> userClass = ClassUtils.getUserClass(beanClass);
// 如果是有代理的,找到被代理
if (userClass != beanClass) {
try {
// 获取构造方法
Constructor> superCtor =
userClass.getDeclaredConstructor(candidate.getParameterTypes());
//继续寻找Autowired和value的注解
ann = findAutowiredAnnotation(superCtor);
}
catch (NoSuchMethodException ex) {
// Simply proceed, no equivalent superclass constructor found...
}
}
}
// 构造函数上存在注解
if (ann != null) {
//有两个Autowired注解,冲突了
if (requiredConstructor != null) {
throw new BeanCreationException(beanName,
"Invalid autowire-marked constructor: " + candidate +
". Found constructor with 'required' Autowired annotation already: " +
requiredConstructor);
}
// 获取@Autowired注解中required属性的值
boolean required = determineRequiredStatus(ann);
// 为true则将这个构造函数设置为带有依赖项的构造函数并进行判断,不可存在多个带有依赖项的构造函数
if (required) {
//如果已经有required=false了,又来了一个required=true的方法就报异常了,这样两个可能就不知道用哪个了
if (!candidates.isEmpty()) {
throw new BeanCreationException(beanName,
"Invalid autowire-marked constructors: " + candidates +
". Found constructor with 'required' Autowired annotation: " +
candidate);
}
requiredConstructor = candidate;
}
// 加入集合
candidates.add(candidate);
}
// 如果构造函数的参数为零,则是默认构造函数
else if (candidate.getParameterCount() == 0) {
defaultConstructor = candidate;
}
}
// 存在@Autowired注解的函数,并且required值为false,则此注解不起作用,但是存在默认构造函数
// 则将默认构造函数添加到集合中,并将集合变为数组使用
if (!candidates.isEmpty()) {
// Add default constructor to list of optional constructors, as fallback.
if (requiredConstructor == null) {
if (defaultConstructor != null) {
//添加默认构造函数
candidates.add(defaultConstructor);
}
else if (candidates.size() == 1 && logger.isInfoEnabled()) {
logger.info("Inconsistent constructor declaration on bean with name '" + beanName +
"': single autowire-marked constructor flagged as optional - " +
"this constructor is effectively required since there is no " +
"default constructor to fall back to: " + candidates.get(0));
}
}
candidateConstructors = candidates.toArray(new Constructor>[0]);
}
// 如果只存在一个构造函数,且这个构造函数有参数列表,则使用这个构造函数
else if (rawCandidates.length == 1 && rawCandidates[0].getParameterCount() > 0) {
//只有一个函数且有参数
candidateConstructors = new Constructor>[] {rawCandidates[0]};
}
// 如果非合成构造存在两个且有主构造和默认构造,且主构造和默认构造不相等,则这两个一块使用
else if (nonSyntheticConstructors == 2 && primaryConstructor != null &&
defaultConstructor != null && !primaryConstructor.equals(defaultConstructor)) {
//有两个非合成方法,有优先方法和默认方法,且不相同
candidateConstructors = new Constructor>[] {primaryConstructor, defaultConstructor};
}
// 如果只有一个非合成构造且有主构造,使用主构造
else if (nonSyntheticConstructors == 1 && primaryConstructor != null) {
//只有一个优先的
candidateConstructors = new Constructor>[] {primaryConstructor};
}
// 否则没有能够直接使用的构造
else {
//大于2个没注解的构造方法就不知道要用什么了,所以就返回null
candidateConstructors = new Constructor>[0];
}
this.candidateConstructorsCache.put(beanClass, candidateConstructors);
}
}
}
// 使用构造列表中没有值,则返回null
return (candidateConstructors.length > 0 ? candidateConstructors : null);
}
/**
* 完成bean中@Autowired,@Inject,@Value注解的解析并注入的功能
* @param pvs
* @param bean
* @param beanName
* @return
*/
@Override
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
// 从缓存中取出这个bean对应的依赖注入的元信息~
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;
}
@Deprecated
@Override
public PropertyValues postProcessPropertyValues(
PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) {
return postProcessProperties(pvs, bean, beanName);
}
/**
* 'Native' processing method for direct calls with an arbitrary target instance,
* resolving all of its fields and methods which are annotated with one of the
* configured 'autowired' annotation types.
* @param bean the target instance to process
* @throws BeanCreationException if autowiring failed
* @see #setAutowiredAnnotationTypes(Set)
*/
public void processInjection(Object bean) throws BeanCreationException {
Class> clazz = bean.getClass();
InjectionMetadata metadata = findAutowiringMetadata(clazz.getName(), clazz, null);
try {
metadata.inject(bean, null, null);
}
catch (BeanCreationException ex) {
throw ex;
}
catch (Throwable ex) {
throw new BeanCreationException(
"Injection of autowired dependencies failed for class [" + clazz + "]", ex);
}
}
/**
* 方法名为查找到该bean的依赖注入元信息,内部只要查找到了就会加入到缓存内,下次没必要再重复查找了~
* 它是一个模版方法,真正做事的方法是:buildAutowiringMetadata,它复杂把标注有@Autowired注解的属性转换为Metadata元数据信息,从而消除注解的定义
* 此处查找包括了字段依赖注入和方法依赖注入~~~
* @param beanName
* @param clazz
* @param pvs
* @return
*/
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) {
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;
}
/**
* 去寻找有Autowired和Value注解的属性和方法,也包括自定义的父类的,封装成AutowiredMethodElement放入集合中
* @param clazz
* @return
*/
private InjectionMetadata buildAutowiringMetadata(final Class> clazz) {
// 如果clazz是JDK中的类,直接忽略,因为不可能标注有这些标注
if (!AnnotationUtils.isCandidateClass(clazz, this.autowiredAnnotationTypes)) {
return InjectionMetadata.EMPTY;
}
List elements = new ArrayList<>();
Class> targetClass = clazz;
do {
final List currElements = new ArrayList<>();
// 遍历类中的每个属性,判断属性是否包含指定的属性(通过 findAutowiredAnnotation 方法)
// 如果存在则保存,这里注意,属性保存的类型是 AutowiredFieldElement
ReflectionUtils.doWithLocalFields(targetClass, field -> {
MergedAnnotation> ann = findAutowiredAnnotation(field);
if (ann != null) {
//Autowired注解不支持静态方法
if (Modifier.isStatic(field.getModifiers())) {
if (logger.isInfoEnabled()) {
logger.info("Autowired annotation is not supported on static fields: " + field);
}
return;
}
//查看是否是required的
boolean required = determineRequiredStatus(ann);
currElements.add(new AutowiredFieldElement(field, required));
}
});
// 遍历类中的每个方法,判断属性是否包含指定的属性(通过 findAutowiredAnnotation 方法)
// 如果存在则保存,这里注意,方法保存的类型是 AutowiredMethodElement
ReflectionUtils.doWithLocalMethods(targetClass, method -> {
Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
if (!BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) {
return;
}
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);
}
}
boolean required = determineRequiredStatus(ann);
PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
// AutowiredMethodElement里封装了一个PropertyDescriptor(比字段多了一个参数)
currElements.add(new AutowiredMethodElement(method, required, pd));
}
});
// 父类的都放在第一位,所以父类是最先完成依赖注入的
elements.addAll(0, currElements);
targetClass = targetClass.getSuperclass();
}
while (targetClass != null && targetClass != Object.class);
// InjectionMetadata就是对clazz和elements的一个包装而已
return InjectionMetadata.forElements(elements, clazz);
}
/**
* 只要方法/属性上但凡标注有一个注解,就立马返回了
* @param ao
* @return
*/
@Nullable
private MergedAnnotation> findAutowiredAnnotation(AccessibleObject ao) {
MergedAnnotations annotations = MergedAnnotations.from(ao);
for (Class extends Annotation> type : this.autowiredAnnotationTypes) {
MergedAnnotation> annotation = annotations.get(type);
if (annotation.isPresent()) {
return annotation;
}
}
return null;
}
/**
* Determine if the annotated field or method requires its dependency.
* A 'required' dependency means that autowiring should fail when no beans
* are found. Otherwise, the autowiring process will simply bypass the field
* or method when no beans are found.
* @param ann the Autowired annotation
* @return whether the annotation indicates that a dependency is required
*/
@SuppressWarnings({"deprecation", "cast"})
protected boolean determineRequiredStatus(MergedAnnotation> ann) {
// The following (AnnotationAttributes) cast is required on JDK 9+.
return determineRequiredStatus((AnnotationAttributes)
ann.asMap(mergedAnnotation -> new AnnotationAttributes(mergedAnnotation.getType())));
}
/**
* Determine if the annotated field or method requires its dependency.
*
A 'required' dependency means that autowiring should fail when no beans
* are found. Otherwise, the autowiring process will simply bypass the field
* or method when no beans are found.
* @param ann the Autowired annotation
* @return whether the annotation indicates that a dependency is required
* @deprecated since 5.2, in favor of {@link #determineRequiredStatus(MergedAnnotation)}
*/
@Deprecated
protected boolean determineRequiredStatus(AnnotationAttributes ann) {
return (!ann.containsKey(this.requiredParameterName) ||
this.requiredParameterValue == ann.getBoolean(this.requiredParameterName));
}
/**
* Obtain all beans of the given type as autowire candidates.
* @param type the type of the bean
* @return the target beans, or an empty Collection if no bean of this type is found
* @throws BeansException if bean retrieval failed
*/
protected Map findAutowireCandidates(Class type) throws BeansException {
if (this.beanFactory == null) {
throw new IllegalStateException("No BeanFactory configured - " +
"override the getBeanOfType method or specify the 'beanFactory' property");
}
return BeanFactoryUtils.beansOfTypeIncludingAncestors(this.beanFactory, type);
}
/**
* Register the specified bean as dependent on the autowired beans.
*/
private void registerDependentBeans(@Nullable String beanName, Set autowiredBeanNames) {
if (beanName != null) {
for (String autowiredBeanName : autowiredBeanNames) {
if (this.beanFactory != null && this.beanFactory.containsBean(autowiredBeanName)) {
this.beanFactory.registerDependentBean(autowiredBeanName, beanName);
}
if (logger.isTraceEnabled()) {
logger.trace("Autowiring by type from bean name '" + beanName +
"' to bean named '" + autowiredBeanName + "'");
}
}
}
}
/**
* Resolve the specified cached method argument or field value.
*/
@Nullable
private Object resolvedCachedArgument(@Nullable String beanName, @Nullable Object cachedArgument) {
if (cachedArgument instanceof DependencyDescriptor) {
DependencyDescriptor descriptor = (DependencyDescriptor) cachedArgument;
Assert.state(this.beanFactory != null, "No BeanFactory available");
return this.beanFactory.resolveDependency(descriptor, beanName, null, null);
}
else {
return cachedArgument;
}
}
/**
* Class representing injection information about an annotated field.
*/
private class AutowiredFieldElement extends InjectionMetadata.InjectedElement {
private final boolean required;
private volatile boolean cached = false;
@Nullable
private volatile Object cachedFieldValue;
public AutowiredFieldElement(Field field, boolean required) {
super(field, null);
this.required = required;
}
/**
* 完成属性的注入
* @param bean
* @param beanName
* @param pvs
* @throws Throwable
*/
@Override
protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
Field field = (Field) this.member;
Object value;
// 如果缓存,从缓存中获取
if (this.cached) {
// 如果 cachedFieldValue instanceof DependencyDescriptor。则调用 resolveDependency 方法重新加载。
value = resolvedCachedArgument(beanName, this.cachedFieldValue);
}
else {
// 否则调用了 resolveDependency 方法。这个在前篇讲过,在 populateBean 方法中按照类型注入的时候就是通过此方法,
// 也就是说明了 @Autowired 和 @Inject默认是 按照类型注入的
DependencyDescriptor desc = new DependencyDescriptor(field, this.required);
desc.setContainingClass(bean.getClass());
Set autowiredBeanNames = new LinkedHashSet<>(1);
Assert.state(beanFactory != null, "No BeanFactory available");
// 转换器使用的bean工厂的转换器
TypeConverter typeConverter = beanFactory.getTypeConverter();
try {
// 获取依赖的value值的工作 最终还是委托给beanFactory.resolveDependency()去完成的
// 这个接口方法由AutowireCapableBeanFactory提供,它提供了从bean工厂里获取依赖值的能力
value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
}
catch (BeansException ex) {
throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(field), ex);
}
// 把缓存值缓存起来
synchronized (this) {
// 如果没有缓存,则开始缓存
if (!this.cached) {
// 可以看到value!=null并且required=true才会进行缓存的处理
if (value != null || this.required) {
// 这里先缓存一下 desc,如果下面 utowiredBeanNames.size() > 1。则在上面从缓存中获取的时候会重新获取。
this.cachedFieldValue = desc;
// 注册依赖bean
registerDependentBeans(beanName, autowiredBeanNames);
// autowiredBeanNames里可能会有别名的名称,所以size可能大于1
if (autowiredBeanNames.size() == 1) {
// beanFactory.isTypeMatch挺重要的,因为@Autowired是按照类型注入的
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) {
// 通过反射,给属性赋值
ReflectionUtils.makeAccessible(field);
field.set(bean, value);
}
}
}
/**
* Class representing injection information about an annotated method.
*/
private class AutowiredMethodElement extends InjectionMetadata.InjectedElement {
private final boolean required;
private volatile boolean cached = false;
@Nullable
private volatile Object[] cachedMethodArguments;
public AutowiredMethodElement(Method method, boolean required, @Nullable PropertyDescriptor pd) {
super(method, pd);
this.required = required;
}
/**
* 完成方法的注入
* @param bean
* @param beanName
* @param pvs
* @throws Throwable
*/
@Override
protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
// 检测是否可以跳过
if (checkPropertySkipping(pvs)) {
return;
}
// 获取方法
Method method = (Method) this.member;
Object[] arguments;
// 如果缓存中有,从缓存中获取
if (this.cached) {
// Shortcut for avoiding synchronization...
arguments = resolveCachedArguments(beanName);
}
else {
// 获取方法的参数,从Spring 容器中获取(缓存中没有则尝试创建)
int argumentCount = method.getParameterCount();
arguments = new Object[argumentCount];
DependencyDescriptor[] descriptors = new DependencyDescriptor[argumentCount];
Set autowiredBeans = new LinkedHashSet<>(argumentCount);
Assert.state(beanFactory != null, "No BeanFactory available");
TypeConverter typeConverter = beanFactory.getTypeConverter();
// 遍历参数从容器中获取
for (int i = 0; i < arguments.length; i++) {
MethodParameter methodParam = new MethodParameter(method, i);
DependencyDescriptor currDesc = new DependencyDescriptor(methodParam, this.required);
currDesc.setContainingClass(bean.getClass());
descriptors[i] = currDesc;
try {
// 根据类型从容器中获取
Object arg = beanFactory.resolveDependency(currDesc, beanName, autowiredBeans, typeConverter);
if (arg == null && !this.required) {
arguments = null;
break;
}
arguments[i] = arg;
}
catch (BeansException ex) {
throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(methodParam), ex);
}
}
synchronized (this) {
if (!this.cached) {
if (arguments != null) {
DependencyDescriptor[] cachedMethodArguments = Arrays.copyOf(descriptors, arguments.length);
registerDependentBeans(beanName, autowiredBeans);
if (autowiredBeans.size() == argumentCount) {
Iterator it = autowiredBeans.iterator();
Class>[] paramTypes = method.getParameterTypes();
for (int i = 0; i < paramTypes.length; i++) {
String autowiredBeanName = it.next();
if (beanFactory.containsBean(autowiredBeanName) &&
beanFactory.isTypeMatch(autowiredBeanName, paramTypes[i])) {
cachedMethodArguments[i] = new ShortcutDependencyDescriptor(
descriptors[i], autowiredBeanName, paramTypes[i]);
}
}
}
this.cachedMethodArguments = cachedMethodArguments;
}
else {
this.cachedMethodArguments = null;
}
this.cached = true;
}
}
}
if (arguments != null) {
try {
// 通过反射,调用注解标注的方法
ReflectionUtils.makeAccessible(method);
method.invoke(bean, arguments);
}
catch (InvocationTargetException ex) {
throw ex.getTargetException();
}
}
}
@Nullable
private Object[] resolveCachedArguments(@Nullable String beanName) {
Object[] cachedMethodArguments = this.cachedMethodArguments;
if (cachedMethodArguments == null) {
return null;
}
Object[] arguments = new Object[cachedMethodArguments.length];
for (int i = 0; i < arguments.length; i++) {
arguments[i] = resolvedCachedArgument(beanName, cachedMethodArguments[i]);
}
return arguments;
}
}
/**
* DependencyDescriptor variant with a pre-resolved target bean name.
*/
@SuppressWarnings("serial")
private static class ShortcutDependencyDescriptor extends DependencyDescriptor {
private final String shortcut;
private final Class> requiredType;
public ShortcutDependencyDescriptor(DependencyDescriptor original, String shortcut, Class> requiredType) {
super(original);
this.shortcut = shortcut;
this.requiredType = requiredType;
}
@Override
public Object resolveShortcut(BeanFactory beanFactory) {
return beanFactory.getBean(this.shortcut, this.requiredType);
}
}
}