一、概念:@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类中。
//源码中的预加载方法
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition,
Class> beanType, String beanName) {
InjectionMetadata metadata
= this.findAutowiringMetadata(beanName, beanType, (PropertyValues)null);
metadata.checkConfigMembers(beanDefinition);
}
// 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;
}
private InjectionMetadata buildAutowiringMetadata(Class> clazz) {
LinkedList elements = new LinkedList();
Class targetClass = clazz;
do {
LinkedList 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);
}
1》通过反射获取目标类中所有的字段并进行遍历,然后通过findAutowiredAnnotation()方法判断字段是否使用@Autowired和@Value修饰,如果字段被@Autowired和@Value修饰,则返回注解的所有属性信息。
2》通过反射获取目标类中所有的方法;
3》解析到字段和方法的元信息保存到List
4》将目标类对应的所有自动注入相关的元信息封装成InjectionMetadata类,返回
buildAutowiringMetadata()方法执行完成后,会将解析得到的自动注入相关信息保存到缓存injectionMetadataCache
public class InjectionMetadata {
private static final Log logger = LogFactory.getLog(InjectionMetadata.class);
private final Class> targetClass;
private final Collection injectedElements;
@Nullable
private volatile Set checkedElements;
public InjectionMetadata(Class> targetClass, Collection elements) {
this.targetClass = targetClass;
this.injectedElements = elements;
}
public void checkConfigMembers(RootBeanDefinition beanDefinition) {
Set 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()方法实现自动注入属性。
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 checkedElements = this.checkedElements;
Collection 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)方法是关键