【Spring源碼】15.IOC之AnnotationConfigApplicationContext基于注解的上下文

image

1.前言

前面幾章 講過(guò) ClassPathXmlApplicationContext 是基于xml配置文件 來(lái)加載 spring 容器的:包括注冊(cè)什么bean,掃描哪些包,事務(wù),等等都是配置xml文件里,維護(hù)這個(gè)配置文件非常的困難。

所以就有了 基于注解的配置形式,由AnnotationConfigApplicationContext 上下文支持。需要以注解的配置形式來(lái)支持 xml配置文件所支持 的所有功能。

接下來(lái)我們通過(guò)源碼來(lái)一一分析下。

2.AnnotationConfigApplicationContext 構(gòu)造方法

public AnnotationConfigApplicationContext(String... basePackages) {
   this();
   scan(basePackages);
   refresh();
}

接收的參數(shù) 為要 掃描的包 路徑。

2.1 this()方法

第一行就是 this();

image

會(huì)初始化AnnotatedBeanDefinitionReader和ClassPathBeanDefinitionScanner屬性。

2.1.1. 初始化AnnotatedBeanDefinitionReader

AnnotatedBeanDefinitionReader的構(gòu)造方法中,會(huì)注冊(cè)很多有用的BeanDefinitionRegistryPostProcessor類型的類,用來(lái)支持注解配置。

這個(gè)工作在基于xml配置解析中是用 在解析自定義標(biāo)簽 <conext:conpment-scan>的時(shí)候完成的,這里基于注解的 由構(gòu)造方法里來(lái)注冊(cè)。

image
image
image

這個(gè)方法會(huì)注冊(cè)很多的BeanDefinitionRegistryPostProcessor類型的類,比較重要的是這幾個(gè)

1. 注冊(cè) ConfigurationClassPostProcessor

這個(gè)類用來(lái)支持 @ComponentScan,@Bean,@Import等注解,非常重要

image

2.注冊(cè) AutowiredAnnotationBeanPostProcessor

這個(gè)類之前依賴注入的時(shí)候講過(guò)了,用來(lái)支持@Autowired和@Value注解的

image

3.注冊(cè)CommonAnnotationBeanPostProcessor

這個(gè)類之前依賴注入的時(shí)候講過(guò),用來(lái)支持@Resource依賴注入,以及方法上的@PostConstruct 和 @PreDestroy

image

2.1.2. 初始化ClassPathBeanDefinitionScanner

ClassPathBeanDefinitionScanner類 這個(gè)就是掃描器,基于包路徑掃描,@ComponentScan 就是用的這個(gè)掃描器去掃描特定包下 的 含有@Component注解的類,并注冊(cè)beanDefinition。

image

構(gòu)造方法里的scan就要用他。

2.2. scan(basePackages);

AnnotationConfigApplicationContext的構(gòu)造方法里要傳入一個(gè)包路徑,基于這個(gè)包路徑 去掃描 需要注冊(cè)的bean

image

這里就會(huì)用到 上一個(gè)方法 實(shí)例化的 ClassPathBeanDefinitionScanner 掃描器進(jìn)行掃描。

image

掃出來(lái)需要注冊(cè)的類,創(chuàng)建BeanDefinition對(duì)象,注冊(cè)進(jìn)去,后續(xù)實(shí)例化
image

2.2.1. 掃包

這個(gè)掃包的邏輯就是 遞歸的去掃,遍歷每一個(gè)類文件,判斷類上是否有 @Component注解,有的話返回

image

2.2.2. 判斷是否需要注冊(cè)

一個(gè)排除的過(guò)濾器集合,命中就 不需要注冊(cè),空的

一個(gè) 包含的過(guò)濾器集合,命中就可能需要注冊(cè),如果有@@Conditional,還需要判斷@Conditional注解,邏輯在isConditionMatch方法中。

image

命中的過(guò)濾器,就是判斷有沒(méi)有 @Component注解,

image

2.3 refresh();

這個(gè)方法和ClassPathXmlApplicationContext 調(diào)的一樣,都是父類的AbstractApplicationContext方法,是spring啟動(dòng)的核心方法。

3.總結(jié)

其實(shí)這個(gè)上下文 和 基于xml配置文件的上下文 殊途同歸。差別最大的 是 ConfigurationClassPostProcessor,AutowiredAnnotationBeanPostProcessor ,CommonAnnotationBeanPostProcessor 這幾個(gè)類的注冊(cè)條件不一樣,在基于注解的上下文里,這幾個(gè)類 是默認(rèn)需要注冊(cè)的,它們所做的工作也沒(méi)有差別。
由于xml配置的方式 在spring工程中已幾近淘汰,后續(xù)其他功能的源碼分析,我們就從AnnotationConfigApplicationContext的配置方式出發(fā)。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容