入口代码:
public class SpringAnnotationStarter {
public static void main(String[] args) {
//创建一个新的AnnotationConfigApplicationContext,从给定的组件类派生bean定义并自动刷新上下文。
new AnnotationConfigApplicationContext(SpringAnnotationConfig.class);
}
}
复制代码
在上面的测试中,使用的AnnotationConfigApplicationContext来刷新上下文,传入参数是我们定义的配置类。
public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
this();
register(componentClasses);
refresh();
}
复制代码
点进去可以发现,首先是调用空参构造器,然后是注册配置类,最后刷新,所以从这三个步骤进行梳理
1. this()
这就是一个空参构造器。
public AnnotationConfigApplicationContext() {
this.reader = new AnnotatedBeanDefinitionReader(this);
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
复制代码
从代码可以看出,是给reader和scanner两个属性进行赋值。
reader的类型是AnnotatedBeanDefinitionReader ,点进去看源码,这是个适配器,也就是adapter,用于bean类的编程注册,解析带有注解的bean的beanDefinition。在reader的赋值如下:
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {
this(registry, getOrCreateEnvironment(registry));
}
复制代码
传入当前类,并且根据当前环境调用重载的构造进行上下文创建,getOrCreateEnvironment看名字大概就是没有创建,有就获取,这就不看了,直接去关注重载的构造器
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
Assert.notNull(environment, "Environment must not be null");
this.registry = registry;
this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
}
复制代码
这里ConditionEvaluator点进去是为context赋值,根据上下文创建一个ConditionContextImpl。
关键在于AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
AnnotationConfigUtils
是一个Spring
内部工具类,用于识别注解配置类中的bean
定义,registerAnnotationConfigProcessors是为在给定的注册表中注册所有后置处理器,也就是PostProcessor。包括一些核心注解,形如:if(!registry.containsBeanDefinition(XXXXXX