一、bean实例化后会调用postProcessMergedBeanDefinition后置处理器寻找注入点AutowiredAnnotationBeanPostProcessor#postProcessMergedBeanDefinition
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) {
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);
}
//第一次缓存中肯定是没数据的
metadata = this.buildAutowiringMetadata(clazz);
this.injectionMetadataCache.put(cacheKey, metadata);
}
}
}
return metadata;
}
三、寻找注入点buildAutowiringMetadata(Class> clazz)
private InjectionMetadata buildAutowiringMetadata(Class> clazz) {
if (!AnnotationUtils.isCandidateClass(clazz, this.autowiredAnnotationTypes)) {
return InjectionMetadata.EMPTY;
}
List elements = new ArrayList<>();
Class> targetClass = clazz;
do {
final List currElements = new ArrayList<>();
//遍历所有属性
ReflectionUtils.doWithLocalFields(targetClass, field -> {
//查看属性上是否有@Autowired、@Value @Inject注解
MergedAnnotation> ann = findAutowiredAnnotation(field);
if (ann != null) {
//静态属性不是注入点直接返回,@Resource中静态属性会报错(CommonAnnotationBeanPostProcessor处理@Resource)
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));
}
});
//遍历所有方法
ReflectionUtils.doWithLocalMethods(targetClass, method -> {
//此刻筛选掉桥接方法(父类泛型相关)子类继承父类的方法加上@Autowired注解,此刻子类会有两个方法,一个是父类桥接、一个自己实现的,过滤掉桥接方法
Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
if (!BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) {
return;
}
查看方法上是否有@Autowired、@Value @Inject注解
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);
//把是Setget相关方法属性描述返回(我们在修改beandefinition中为属性赋值,这里优先级会高)
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 InjectionMetadata.forElements(elements, clazz);
}
匹配属性、方法是否匹配
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;
}
//创建AutowiredAnnotationBeanPostProcessor时autowiredAnnotationTypes添加要扫描的注解
public AutowiredAnnotationBeanPostProcessor() {
this.autowiredAnnotationTypes.add(Autowired.class);
this.autowiredAnnotationTypes.add(Value.class);
try {
this.autowiredAnnotationTypes.add((Class extends Annotation>)
ClassUtils.forName("jakarta.inject.Inject", AutowiredAnnotationBeanPostProcessor.class.getClassLoader()));
logger.trace("'jakarta.inject.Inject' annotation found and supported for autowiring");
}
catch (ClassNotFoundException ex) {
// jakarta.inject API not available - simply skip.
}
try {
this.autowiredAnnotationTypes.add((Class extends Annotation>)
ClassUtils.forName("javax.inject.Inject", AutowiredAnnotationBeanPostProcessor.class.getClassLoader()));
logger.trace("'javax.inject.Inject' annotation found and supported for autowiring");
}
catch (ClassNotFoundException ex) {
// javax.inject API not available - simply skip.
四、桥接方法的筛选demo
public interface UserInterface{ void setOrderService(T t); } @Component public class UserService implements UserInterface { private OrderService orderService; @Override @Autowired public void setOrderService(OrderService orderService) { this.orderService = orderService; } public void test() { System.out.println("test123"); } }
UserService对应的字节码为会存在以下两个方法:
可以看到在UserSerivce的字节码中有两个setOrderService方法:
- public setOrderService(Lcom/zhouyu/service/OrderService;)V
- public synthetic bridge setOrderService(Ljava/lang/Object;)V
并且都是存在@Autowired注解的。
所以在Spring中需要处理这种情况,当遍历到桥接方法时,得找到原方法。
五、总结
1. 遍历当前类的所有的属性字段Field
2. 查看字段上是否存在@Autowired、@Value、@Inject中的其中任意一个,存在则认为该字段
是一个注入点
3. 如果字段是static的,则不进行注入
4. 获取@Autowired中的required属性的值
5. 将字段信息构造成一个AutowiredFieldElement对象,作为一个注入点对象添加到
currElements集合中。
6. 遍历当前类的所有方法Method
7. 判断当前Method是否是桥接方法,如果是找到原方法
8. 查看方法上是否存在@Autowired、@Value、@Inject中的其中任意一个,存在则认为该方法
是一个注入点
9. 如果方法是static的,则不进行注入
10. 获取@Autowired中的required属性的值
11. 将方法信息构造成一个AutowiredMethodElement对象,作为一个注入点对象添加到
currElements集合中。
12. 遍历完当前类的字段和方法后,将遍历父类的,直到没有父类。
13. 最后将currElements集合封装成一个InjectionMetadata对象,作为当前Bean对于的注入点集合
对象,并缓存。



