基于 Annotation 的依赖注入

1.AnnotationConfigApplicationContext对注解Bean初始化:
Spring中,管理注解Bean定义的容器有两个:AnnotationConfigApplicationContext和AnnotationConfigWebApplicationContex。这两个类是专门处理Spring注解方式配置的容器,直
接依赖于注解作为容器配置信息来源的IOC容器。AnnotationConfigWebApplicationContext是AnnotationConfigApplicationContext的web版本,两者的用法以及对注解的处理方式几乎没有什么差别。

看看AnnotationConfigApplicationContext的源码:

通过对AnnotationConfigApplicationContext的源码分析,我们了解到Spring对注解的处理分为两种方式:
(1).直接将注解Bean注册到容器中:
可以在初始化容器时注册;也可以在容器创建之后手动调用注册方法向容器注册,然后通过手动刷新容器,使得容器对注册的注解Bean进行处理。

(2).通过扫描指定的包及其子包下的所有类:

在初始化注解容器时指定要自动扫描的路径,如果容器创建以后向给定路径动态添加了注解Bean,则需要手动调用容器扫描的方法,然后手动刷新容器,使得容器对所注册的Bean进行处理。接下来,将会对两种处理方式详细分析其实现过程。

3.AnnotationConfigApplicationContext注册注解Bean
当创建注解处理容器时,如果传入的初始参数是具体的注解Bean定义类时,注解容器读取并注册。

(1).AnnotationConfigApplicationContext通过调用注解Bean定义读取器AnnotatedBeanDefinitionReader的register方法向容器注册指定的注解Bean,注解Bean定义读取器向容器注册注解Bean的源码:

从上面的源码我们可以看出,注册注解Bean定义类的基本步骤:
a,需要使用注解元数据解析器解析注解Bean中关于作用域的配置。
b,使用AnnotationConfigUtils的processCommonDefinitionAnnotations方法处理注解Bean定义类中通用的注解。
c,使用AnnotationConfigUtils的applyScopedProxyMode方法创建对于作用域的代理对象。
d,通过BeanDefinitionReaderUtils向容器注册Bean。
下面我们继续分析这3步的具体实现过程

(2).AnnotationScopeMetadataResolver解析作用域元数据:AnnotationScopeMetadataResolver通过processCommonDefinitionAnnotations方法解析注解Bean定义类的作用域元信息,即判断注册的Bean是原生类型(prototype)还是单态(singleton)类型,其源码:

上述代码中的 annDef.getMetadata().getAnnotationAttributes 方法就是获取对象中指定类型的注解的值

(3).AnnotationConfigUtils 处理注解 Bean 定义类中的通用注解
AnnotationConfigUtils 类的 processCommonDefinitionAnnotations 在向容器注册 Bean 之前,

首先对注解 Bean 定义类中的通用 Spring 注解进行处理, 源码


(4).AnnotationConfigUtils 根据注解 Bean 定义类中配置的作用域为其应用相应的代理策略

AnnotationConfigUtils 类的 applyScopedProxyMode 方法根据注解 Bean 定义类中配置的作用域@Scope 注解的值, 为 Bean 定义应用相应的代理模式, 主要是在 Spring 面向切面编程(AOP)中使用。源码:


(5).BeanDefinitionReaderUtils 向容器注册 Bean

BeanDefinitionReaderUtils向容器注册载入的Bean前面博客中已经分析过,主要是校验Bean 定义,然后将 Bean 添加到容器中一个管理Bean定义的HashMap中,这里就不做分析。

2.AnnotationConfigApplicationContext 扫描指定包及其子包下的注解 Bean

当创建注解处理容器时, 如果传入的初始参数是注解 Bean 定义类所在的包时, 注解容器将扫描给定的包及其子包, 将扫描到的注解包及其子包, 将扫描到的注解 Bean 定义载入并注册。

(1).ClassPathBeanDefinitionScanner 扫描给定的包及其子包:
AnnotationConfigApplicationContext 通 过 调 用 类 路 径 Bean 定 义 扫 描 器 ClassPathBeanDefinitionScanner 扫描给定包及其子包下的所有类, 主要源码如下

类路径Bean定义扫描器ClassPathBeanDefinitionScanner主要通过findCandidateComponents方法调用其父类ClassPathScanningCandidateComponentProvider类来扫描获取给定包及其子包下的类。

(2).ClassPathScanningCandidateComponentProvider 扫描给定包及其子包的类
ClassPathScanningCandidateComponentProvider类的findCandidateComponents方法具体实现

扫描给定类路径包的功能,源码:


3.AnnotationConfigWebApplicationContext 载入注解 Bean 定义

AnnotationConfigWebApplicationContext AnnotationConfigApplicationContext Web 版,它们对于注解 Bean 的注册和扫描是基本相同的, 但是 AnnotationConfigWebApplicationContext对注解 Bean 定义的载入稍有不同, AnnotationConfigWebApplicationContext 注入注解 Bean 定义源码:


解析和注入注解配置资源的过程分析


上一篇: 基于 XML 的依赖注入

下一篇: IOC容器中常用扩展点

猜你喜欢

转载自blog.csdn.net/m0_37444820/article/details/80793742