@Autowired的作用是自动装配,那么@Autowired是如何实现这个功能的呢?
我们进入@Autowired的源码看看
一、@Autowired的放置位置
首先可以看到Autowired上有三个注解,其中@Traget限制了Autowired的放置位置
@Autowired可以放置在构造方法、普通方法、参数、属性以及另一个注解上。
//@Target注解的作用是:指定可以放置注解的位置
@Target({ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Autowired {
boolean required() default true;
}
二、@Autowired的实现原理
Spring对autowire注解的实现逻辑位于类:AutowiredAnnotationBeanPostProcessor(
后置处理器)
。 它实现了MergedBeanDefinitionPostProcessor接口,进而实现了接口中的 postProcessMergedBeanDefinition方法,@Autowired注解正是通过这个方法实现注入类型的预解析,将需要依赖注入的属性信息封装到InjectionMetadata类中。
Spring容器启动时,AutowiredAnnotationBeanPostProcessor被注册到容器(refresh方法中registerBeanPostProcessors(beanFactory)),当执行finishBeanFactoryInitialization(beanFactory)方法对非延迟初始化的单例bean进行初始化时,会执行到AbstractAutowireCapableBeanFactory类的doCreateBean方法。在此方法中会执行applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName)。深入方法中会发现最后调用的是AutowiredAnnotationBeanPostProcessor类的postProcessMergedBeanDefinition方法。
postProcessMergedBeanDefinition方法
此方法调用findAutoWringMetadata方法,是为了找到需要自动装配的元素。
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
InjectionMetadata metadata = this.findAutowiringMetadata(beanName, beanType, (PropertyValues)null);
metadata.checkConfigMembers(beanDefinition);
}
findAutoWiringMetadata方法
该方法会去调用buildAutowiringMetadata()方法构建元数据信息。
private InjectionMetadata findAutowiringMetadata(String beanName, Class<?> clazz, @Nullable PropertyValues pvs) {
String cacheKey = StringUtils.hasLength(beanName) ? beanName : clazz.getName();
//检查缓存中是否存在bean
InjectionMetadata metadata = (InjectionMetadata)this.injectionMetadataCache.get(cacheKey);
if (InjectionMetadata.needsRefresh(metadata, clazz)) {
synchronized(this.injectionMetadataCache) {
检查缓存中是否存在bean
metadata = (InjectionMetadata)this.injectionMetadataCache.get(cacheKey);
if (InjectionMetadata.needsRefresh(metadata, clazz)) {
if (metadata != null) {
metadata.clear(pvs);
}
// 获取目标类对应的自动注入相关的元数据信息
metadata = this.buildAutowiringMetadata(clazz);
//存入缓存
this.injectionMetadataCache.put(cacheKey, metadata);
}
}
}
return metadata;
}
buildAutowiringMetadata方法
通过findAutowiredAnnotation(field)方法查找此属性是否被@Autowired注解修饰,如果带有@Autowired注解,通过反射获取目标类中所有的属性、方法,将每个属性或者方法解析到的元信息保存到List<InjectionMetadata.InjectedElement> elements集合中,属性对应的是AutowiredFieldElement类型,方法对应的则是AutowiredMethodElement类型。将所有的元信息封装成InjectionMetadata并返回。
private InjectionMetadata buildAutowiringMetadata(final Class<?> clazz) {
List<InjectionMetadata.InjectedElement> elements = new ArrayList<>();
Class<?> targetClass = clazz;
do {
// 存放找到的元数据信息
final List<InjectionMetadata.InjectedElement> currElements = new ArrayList<>();
// 通过反射获取目标类中所有的字段,并遍历每一个字段,然后通过findAutowiredAnnotation()方法判断字段是否使用@Autowired和@Value修饰,
// 如果字段被@Autowired和@Value修饰,则返回注解的相关属性信息
ReflectionUtils.doWithLocalFields(targetClass, field -> {
// findAutowiredAnnotation(): 判断字段是否使用@Autowired和@Value修饰,并返回相关属性
AnnotationAttributes ann = findAutowiredAnnotation(field);
if (ann != null) {
// 校验@Autowired和@Value修饰注解是否应用在static方法上
if (Modifier.isStatic(field.getModifiers())) {
if (logger.isInfoEnabled()) {
logger.info("Autowired annotation is not supported on static fields: " + field);
}
return;
}
// 获取到@Autowired注解的required()的值
boolean required = determineRequiredStatus(ann);
// 将该字段封成AutowiredFieldElement对象
currElements.add(new AutowiredFieldElement(field, required));
}
});
// 前面是通过反射获取目标类中所有的字段,这里是通过反射获取目标类中所有的方法
ReflectionUtils.doWithLocalMethods(targetClass, method -> {
Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
if (!BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) {
return;
}
AnnotationAttributes 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;
}
// 判断方法的参数个数是否为0
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对象
currElements.add(new AutowiredMethodElement(method, required, pd));
}
});
elements.addAll(0, currElements);
targetClass = targetClass.getSuperclass();
}
// 循环处理父类需要自动装配的元素
while (targetClass != null && targetClass != Object.class);
// 将目标类对应的所有自动注入相关的元信息封装成InjectionMetadata,然后合并到Bean定义中
// 包含所有带有@Autowired注解修饰的一个InjectionMetadata集合. 由两部分组成: 一是我们处理的目标类,二就是上述方法获取到的所以elements集合。
return new InjectionMetadata(clazz, elements);
}
执行完doCreateBean方法后,执行populateBean方法。此方法中会执行InstantiationAwareBeanPostProcessor的postProcessProperties方法。深入方法中会发现最后调用的是AutowiredAnnotationBeanPostProcessor的postProcessProperties方法。
postProcessProperties方法
findAutowiringMetadata()方法将目标类对应的@Autowired注解元信息都已经解析好存入到缓存injectionMetadataCache中,所以 这里我们直接从缓存中获取即可。
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
// 首先尝试从缓存injectionMetadataCache中获取对应的注入元信息,如果缓存不存在,将会执行buildAutowiringMetadata()获取
InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
try {
// 循环InjectionMetadata的injectedElements属性,挨个调用InjectionMetadata.InjectedElement.inject方法,通过反射方式设置属性的值
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)方法。
在AutowiredAnnotationBeanPostProcessor类中,定义了AutowiredFieldElement以及AutowiredMethodElement:这两个类继承了InjectMetadata.InjectedElement。所以当执行element.inject(target, beanName, pvs)方法的时候,也是调用AutowiredAnnotationBeanPostProcessor.AutowiredFieldElement或AutowiredMethodElement中的inject()方法。
public void inject(Object target, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
Collection<InjectionMetadata.InjectedElement> checkedElements = this.checkedElements;
Collection<InjectionMetadata.InjectedElement> elementsToIterate = checkedElements != null ? checkedElements : this.injectedElements;
if (!((Collection)elementsToIterate).isEmpty()) {
Iterator var6 = ((Collection)elementsToIterate).iterator();
// 循环elementsToIterate, 挨个调用InjectionMetadata.InjectedElement.inject方法, 通过反射方式设置属性的值;
while(var6.hasNext()) {
InjectionMetadata.InjectedElement element = (InjectionMetadata.InjectedElement)var6.next();
element.inject(target, beanName, pvs);
}
}
}
AutowiredAnnotationBeanPostProcessor.AutowiredFieldElement 中的inject()方法
依赖的对象获取成功后,将会通过反射方式field.set(bean, value)设置bean对象中的被@Autowired修饰的属性的值。
protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
Field field = (Field)this.member;
Object value;
if (this.cached) {
try {
value = AutowiredAnnotationBeanPostProcessor.this.resolvedCachedArgument(beanName, this.cachedFieldValue);
} catch (NoSuchBeanDefinitionException var7) {
value = this.resolveFieldValue(field, bean, beanName);
}
} else {
// 通过beanFactory.resolveDependency()方法从bean工厂中获取依赖的对象。跟踪下resolveDependency()方法可以发现,
//底层会调用到org.springframework.beans.factory.config.DependencyDescriptor中的resolveCandidate()方法,
//而resolveCandidate()方法内部其实是通过beanFactory.getBean("beanName")从bean容器中获取到这个bean对象
value = this.resolveFieldValue(field, bean, beanName);
}
if (value != null) {
//field是bean对象的属性
ReflectionUtils.makeAccessible(field);
field.set(bean, value);
}
}
三、总结:
Spring对autowire注解的实现逻辑位于类:AutowiredAnnotationBeanPostProcessor(
后置处理器)
。
主要分为两个步骤:
1.找出需要自动装配的元素:postProcessMergedBeanDefinition方法;
2.注入属性:postProcessProperties方法;
---------------------------------------------------------------------------------------------------------------------------------
参考:https://blog.youkuaiyun.com/Weixiaohuai/article/details/123005140