专业的编程技术博客社区

网站首页 > 博客文章 正文

Spring中的依赖注入:深入理解@Autowired的寻找过程

baijin 2024-08-20 10:26:08 博客文章 7 ℃ 0 评论

前言

Spring bean生命周期中,注入点的搜索发生在bean实例化完成之后。这是BeanDefinition的一个后置处理器扩展点。

MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition(beanDefinition, mbeanType, beanName)

这里,寻找@Autowired、@Value、@Inject注解的注入点的实现类是:AutowiredAnnotationBeanPostProcessor。

而寻找@Resource注解的注入点的实现类是:CommonAnnotationBeanPostProcessor。

本文将重点讲述@Autowired是如何被找到的。

注入点结构

搜索注入点时,显然需要遍历所有的字段和方法,并将找到的注入点保存到InjectedElement类中。AutowiredAnnotationBeanPostProcessor重新实现了这个类。

  • member:它是Field、Method的父类。
  • pd:属性描述符。
  • cached:标识是否已经被搜索过。
  • cachedFieldValue:这是AutowiredFieldElement类的属性,如果之前已经被搜索过,它会把找到的bean名称和类型封装到ShortcutDependencyDescriptor中,这样下次再来时,直接使用名称进行搜索。
  • cachedMethodArguments:这是AutowiredMethodElement类的属性,与上述类似,只不过是将参数按顺序存储在数组中。

注入点的搜索是Spring的一个扩展点,找到的注入点会被保存在集合中。

public class InjectionMetadata {
 private final Class<?> targetClass;
 //保存注入点的集合
 private final Collection<InjectedElement> injectedElements;
}

对于原型bean,每次注入时都重新搜索注入点会很低效,所以InjectionMetadata会被缓存起来。

public class AutowiredAnnotationBeanPostProcessor{
 private final Map<Class<?>, Constructor<?>[]> candidateConstructorsCache = new ConcurrentHashMap<>(256);
}

AutowiredAnnotationBeanPostProcessor.candidateConstructorsCache

下次再次需要时,会通过bean名称或Class名称在缓存中进行查找,从而避免再次搜索注入点。

搜索注入点

首先,遍历类中所有的Field属性,检查是否有@Autowired、@Value、@Inject注解之一,如果有,并且属性不是静态的,那么它就是一个注入点。

然后,遍历类中所有的Method方法,检查方法上是否存在@Autowired、@Value、@Inject中的任一注解,并且方法不是静态的。

这个过程会持续到遍历父类,直到没有父类为止。

最后,将所有找到的注入点保存到集合中。

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表