@Configuration源码讲解
示例
// ------------------------ 配置文件
@Configuration
public class SpringConfig {
@Bean
public Piano piano() {
return new Piano();
}
@Bean(name = "counter")
public Counter counter() {
return new Counter(12, "Shake it Off", piano());
}
}
// ------------------------ 测试
ApplicationContext annotationContext = new AnnotationConfigApplicationContext("xxxPackagePath");
Counter c = annotationContext.getBean("counter", Counter.class);
Assert.assertEquals("糊涂",c.getName()); //测试AnnotationConfigApplicationContext
以上的代码非常简单, 一眼就能看出关键点就是这个AnnotationConfigApplicationContext类了.
而下面的AnnotationConfigApplicationContext构造函数中, 相信注释已经很清楚了, 这里我们关注的重点当然就是scan(basePackages);方法.至于其它两个方法:
this(); 主要是为了实例化自身的两个重要字段.
refresh(); 这个方法至关重要, 不过不是本文的重点. 所以直接略过.如果读者有兴趣, 可以参见本人下面给出的链接, 或者查阅《Spring源码深度解读》—— 作者在其书中对此方法进行了详尽的解读, 个人觉得还是很值得买一本的
AnnotationConfigApplicationContext.scan 方法
ClassPathBeanDefinitionScanner.scan 方法
AnnotationConfigUtils.registerAnnotationConfigProcessors 方法
ConfigurationClassPostProcessor类
既然此次我们关注的重点是@Configuration, 目光当然就落在ConfigurationClassPostProcessor类上了, 观察其继承链, 鼎鼎大名的BeanFactoryPostProcessor赫然在目. 这个类的关键性就不在这里赘述了.
ConfigurationClassPostProcessor 继承链

所以Spring会回调这两个方法
postProcessBeanDefinitionRegistry(由BeanDefinitionRegistryPostProcessor接口定义)
postProcessBeanFactory(由BeanFactoryPostProcessor接口定义)
BeanDefinitionRegistryPostProcessor接口又继承自BeanFactoryPostProcessor; 依据注释, 前者所定义方法的被执行时机位于后者所定义方法之前.
通过观察上面必将被Spring框架回调的两个方法, 我们可以推测:
这两个方法必将被会调用, 且都只会被调用一次.
在执行顺序是 processConfigBeanDefinitions在先, 而enhanceConfigurationClasses在后.
processConfigBeanDefinitions方法
ConfigurationClassParser类
Parse each @Configuration class — 官方注释
访问级别级别为 package;
位于org.springframework.context.annotation package下
ConfigurationClassBeanDefinitionReader类
这个类的访问级别也是 package.
enhanceConfigurationClasses方法
唯一想要提及的是 如果我们从容器中取出配置类(例如通过springConfig作为key取出上面的定义的SpringConfig)的话, 就会发现, Spring返回给我们的并不是一个原生的SpringConfig实例; 而是类似SpringConfig47a5de53@11935e这样的实例; 这明显就是被CGLIB代理过的.
而原因就发生在 ConfigurationClassPostProcessor类的enhanceConfigurationClasses方法中.
其它暂时略.
Links
Last updated
Was this helpful?