一、概念:@Autowired是spring框架2.5之后出现,用来简化在bean当中需要定义属性实现自动装配的注解,夜市最常见注解之一。
二、作用位置:可以修饰在方法,参数和注解等属性上(以下是源码)
//可以修饰的位置包括, 构造方法, 普通方法, 参数,
@Target({ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.PARAMETER,
/* 字段,*/ /* 注解 */
ElementType.FIELD, ElementType.ANNOTATION_TYPE})
//保留策略是在运行时
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Autowired {
//声明了依赖属性 默认是true
boolean required() default true;
}
从我们看到的Autowired源码中是没有任何关于自动装配的代码的,完成自动装配的代码是在AutowiredAnnotationBeanPostProcessor类中。

<一>找到需要装配的元素并保存(解析Autowired)
1.进源码可以看见,AutowiredAnnotationBeanPostProcessor实现了
MergedBeanDefinitionPostProcessor接口,重写postProcessMergedBeanDefinition()方法,实现的注入类型的预解析。
//源码中的预加载方法
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition,
Class<?> beanType, String beanName) {
InjectionMetadata metadata
= this.findAutowiringMetadata(beanName, beanType, (PropertyValues)null);
metadata.checkConfigMembers(beanDefinition);
}
2.主要逻辑是在findAutowiringMetadata()方法。这个方法主要是找到需要自动装配的元素,该方法会去调用buildAutowiringMetadata()方法构建元数据信息。
// findAutowiringMetadata源码
private InjectionMetadata findAutowiringMetadata(String beanName, Class<?> clazz, @Nullable PropertyValues pvs) {
//缓存Bean的名称
String cacheKey = StringUtils.hasLength(beanName) ? beanName : clazz.getName();
InjectionMetadata metadata = (InjectionMetadata)this.injectionMetadataCache.get(cacheKey);
//判断缓存是否存在
if (InjectionMetadata.needsRefresh(metadata, clazz)) {
synchronized(this.injectionMetadataCache) {
metadata = (InjectionMetadata)this.injectionMetadataCache.get(cacheKey);
if (InjectionMetadata.needsRefresh(metadata, clazz)) {
if (metadata != null) {
metadata.clear(pvs);
}
//目标Bean的元数据信息
metadata = this.buildAutowiringMetadata(clazz);
//存入缓存
this.injectionMetadataCache.put(cacheKey, metadata);
}
}
}
return metadata;
}
3.核心逻辑在buildAutowiringMetadata()方法中
private InjectionMetadata buildAutowiringMetadata(Class<?> clazz) {
LinkedList<InjectedElement> elements = new LinkedList();
Class targetClass = clazz;
do {
LinkedList<InjectedElement> currElements = new LinkedList();
//通过反射获取目标类中所有的字段,并遍历每一个字段,然后通过findAutowiredAnnotation() 方法判断字段是否使用@Autowired和@Value修饰,
// 如果字段被@Autowired和@Value修饰,则返回注解的相关属性信息
ReflectionUtils.doWithLocalFields(targetClass, (field) -> {
AnnotationAttributes ann = this.findAutowiredAnnotation(field);
if (ann != null) {
if (Modifier.isStatic(field.getModifiers())) {
if (this.logger.isWarnEnabled()) {
this.logger.warn("Autowired annotation is not supported on static fields: " + field);
}
return;
}
// 获取到@Autowired注解的required()的值
boolean required = this.determineRequiredStatus(ann);
// 将该字段封成AutowiredFieldElement对象
currElements.add(new AutowiredAnnotationBeanPostProcessor.AutowiredFieldElement(field, required));
}
});
//反射获取目标Bean的所有方法
ReflectionUtils.doWithLocalMethods(targetClass, (method) -> {
Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
if (BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) {
AnnotationAttributes ann = this.findAutowiredAnnotation(bridgedMethod);
if (ann != null && method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
if (Modifier.isStatic(method.getModifiers())) {
if (this.logger.isWarnEnabled()) {
this.logger.warn("Autowired annotation is not supported on static methods: " + method);
}
return;
}
if (method.getParameterCount() == 0 && this.logger.isWarnEnabled()) {
this.logger.warn("Autowired annotation should only be used on methods with parameters: " + method);
}
boolean required = this.determineRequiredStatus(ann);
PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
// 将该字段封成AutowiredMethodElement对象
currElements.add(new AutowiredAnnotationBeanPostProcessor.AutowiredMethodElement(method, required, pd));
}
}
});
elements.addAll(0, currElements);
targetClass = targetClass.getSuperclass();
}
// 循环处理父类需要自动装配的元素
while(targetClass != null && targetClass != Object.class);
// 将目标类对应的所有自动注入相关的元信息封装成InjectionMetadata,然后合并到Bean定义中
return new InjectionMetadata(clazz, elements);
}
buildAutowiringMetadata()方法的步骤:
1》通过反射获取目标类中所有的字段并进行遍历,然后通过findAutowiredAnnotation()方法判断字段是否使用@Autowired和@Value修饰,如果字段被@Autowired和@Value修饰,则返回注解的所有属性信息。
2》通过反射获取目标类中所有的方法;
3》解析到字段和方法的元信息保存到List<InjectionMetadata.InjectedElement> elements集合中,字段对应的是AutowiredFieldElement类型,方法对应的则是AutowiredMethodElement类型。
4》将目标类对应的所有自动注入相关的元信息封装成InjectionMetadata类,返回
buildAutowiringMetadata()方法执行完成后,会将解析得到的自动注入相关信息保存到缓存injectionMetadataCache
4.postProcessMergedBeanDefinition()方法将需要注入的属性信息通过checkConfigMembers()
封装在了InjectionMetadata类中,包含了装配和内装配类的所有信息。
public class InjectionMetadata {
private static final Log logger = LogFactory.getLog(InjectionMetadata.class);
private final Class<?> targetClass;
private final Collection<InjectionMetadata.InjectedElement> injectedElements;
@Nullable
private volatile Set<InjectionMetadata.InjectedElement> checkedElements;
public InjectionMetadata(Class<?> targetClass, Collection<InjectionMetadata.InjectedElement> elements) {
this.targetClass = targetClass;
this.injectedElements = elements;
}
public void checkConfigMembers(RootBeanDefinition beanDefinition) {
Set<InjectionMetadata.InjectedElement> checkedElements = new LinkedHashSet(this.injectedElements.size());
Iterator var3 = this.injectedElements.iterator();
while(var3.hasNext()) {
InjectionMetadata.InjectedElement element = (InjectionMetadata.InjectedElement)var3.next();
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;
}
<二>自动注入属性
AutowiredAnnotationBeanPostProcessor间接实现了InstantiationAwareBeanPostProcessor接口,所以会执行到postProcessProperties()方法实现自动注入属性。
*postProcessProperties()方法的处理流程:
1.调用findAutowiringMetadata()方法,尝试从缓存injectionMetadataCache中获取对应的注入元信息,如果缓存不存在,将会执行buildAutowiringMetadata()获取;
2.循环InjectionMetadata的injectedElements属性,全部调用InjectionMetadata.InjectedElement.inject(bean, beanName, pvs)方法,通过反射方式设置属性的值;
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()) {
// 循环elementsToIterate, 调用InjectionMetadata.InjectedElement.inject方法,通过反射方式设置属性的值;
for (InjectedElement element : elementsToIterate) {
if (logger.isTraceEnabled()) {
logger.trace("Processing injected element of bean '" + beanName + "': " + element);
}
element.inject(target, beanName, pvs);
}
}
}
总结:以上分了两部分去说,一是解析@Autowired方法,到反射获取目标类的属性和方法,到存入injectionMetadataCache中,关键是buildAutowiringMetadata()方法。二是自动注入属性,还是反射的方式,取injectionMetadataCache中元信息,inject(bean, beanName, pvs)方法是关键