1.前言
前面幾章 講過 ClassPathXmlApplicationContext 是基于xml配置文件 來加載 spring 容器的:包括注冊什么bean,掃描哪些包蹬竖,事務(wù)拾并,等等都是配置xml文件里课兄,維護這個配置文件非常的困難钦幔。
所以就有了 基于注解的配置形式,由AnnotationConfigApplicationContext 上下文支持。需要以注解的配置形式來支持 xml配置文件所支持 的所有功能。
接下來我們通過源碼來一一分析下殉簸。
2.AnnotationConfigApplicationContext 構(gòu)造方法
public AnnotationConfigApplicationContext(String... basePackages) {
this();
scan(basePackages);
refresh();
}
接收的參數(shù) 為要 掃描的包 路徑。
2.1 this()方法
第一行就是 this();
會初始化AnnotatedBeanDefinitionReader和ClassPathBeanDefinitionScanner屬性沽讹。
2.1.1. 初始化AnnotatedBeanDefinitionReader
AnnotatedBeanDefinitionReader的構(gòu)造方法中,會注冊很多有用的BeanDefinitionRegistryPostProcessor類型的類般卑,用來支持注解配置。
這個工作在基于xml配置解析中是用 在解析自定義標簽 <conext:conpment-scan>的時候完成的爽雄,這里基于注解的 由構(gòu)造方法里來注冊蝠检。
這個方法會注冊很多的BeanDefinitionRegistryPostProcessor類型的類,比較重要的是這幾個
1. 注冊 ConfigurationClassPostProcessor
這個類用來支持 @ComponentScan,@Bean,@Import等注解盲链,非常重要
2.注冊 AutowiredAnnotationBeanPostProcessor
這個類之前依賴注入的時候講過了蝇率,用來支持@Autowired和@Value注解的
3.注冊CommonAnnotationBeanPostProcessor
這個類之前依賴注入的時候講過,用來支持@Resource依賴注入刽沾,以及方法上的@PostConstruct 和 @PreDestroy
2.1.2. 初始化ClassPathBeanDefinitionScanner
ClassPathBeanDefinitionScanner類 這個就是掃描器本慕,基于包路徑掃描,@ComponentScan 就是用的這個掃描器去掃描特定包下 的 含有@Component注解的類侧漓,并注冊beanDefinition锅尘。
構(gòu)造方法里的scan就要用他。
2.2. scan(basePackages);
AnnotationConfigApplicationContext的構(gòu)造方法里要傳入一個包路徑布蔗,基于這個包路徑 去掃描 需要注冊的bean
這里就會用到 上一個方法 實例化的 ClassPathBeanDefinitionScanner 掃描器進行掃描藤违。
2.2.1. 掃包
這個掃包的邏輯就是 遞歸的去掃,遍歷每一個類文件泽谨,判斷類上是否有 @Component注解璧榄,有的話返回
2.2.2. 判斷是否需要注冊
一個排除的過濾器集合特漩,命中就 不需要注冊,空的
一個 包含的過濾器集合骨杂,命中就可能需要注冊涂身,如果有@@Conditional,還需要判斷@Conditional注解,邏輯在isConditionMatch方法中搓蚪。
命中的過濾器蛤售,就是判斷有沒有 @Component注解,
2.3 refresh();
這個方法和ClassPathXmlApplicationContext 調(diào)的一樣妒潭,都是父類的AbstractApplicationContext方法悴能,是spring啟動的核心方法。
3.總結(jié)
其實這個上下文 和 基于xml配置文件的上下文 殊途同歸杜耙。差別最大的 是 ConfigurationClassPostProcessor斩芭,AutowiredAnnotationBeanPostProcessor 凌外,CommonAnnotationBeanPostProcessor 這幾個類的注冊條件不一樣,在基于注解的上下文里阻肿,這幾個類 是默認需要注冊的谈竿,它們所做的工作也沒有差別团驱。
由于xml配置的方式 在spring工程中已幾近淘汰,后續(xù)其他功能的源碼分析空凸,我們就從AnnotationConfigApplicationContext的配置方式出發(fā)嚎花。