
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();

會(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è)。



這個(gè)方法會(huì)注冊(cè)很多的BeanDefinitionRegistryPostProcessor類型的類,比較重要的是這幾個(gè)
1. 注冊(cè) ConfigurationClassPostProcessor
這個(gè)類用來(lái)支持 @ComponentScan,@Bean,@Import等注解,非常重要

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

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

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

構(gòu)造方法里的scan就要用他。
2.2. scan(basePackages);
AnnotationConfigApplicationContext的構(gòu)造方法里要傳入一個(gè)包路徑,基于這個(gè)包路徑 去掃描 需要注冊(cè)的bean

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


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

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

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

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ā)。