1 入口代码
public class Info {
public static void main(String[] args) {
ApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);
System.out.println(ac.getBean(AppConfig.class).name);
}
}
2 AnnotationConfigApplicationContext
public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
this();
register(componentClasses);
refresh();
}
调用this(),默认无参的构造方法。AnnotationConfigApplicationContext继承GenericApplicationContext。因此在调用自身构造器的时候会隐式的调用父类的构造器。
public GenericApplicationContext() {
this.beanFactory = new DefaultListableBeanFactory();
}
因此在GenericApplicationContext的构造器完成了DefaultListableBeanFactory的初始化。
/**
* 这里会首先初始化父类的构造方法
* public GenericApplicationContext() {
* this.beanFactory = new DefaultListableBeanFactory();
* }
* 因此会实例化beanFactory,也就是DefaultListableBeanFactory
*/
public AnnotationConfigApplicationContext() {
StartupStep createAnnotatedBeanDefReader = this.getApplicationStartup().start("spring.context.annotated-bean-reader.create");
// 基于注解的bean定义读取器
this.reader = new AnnotatedBeanDefinitionReader(this);
createAnnotatedBeanDefReader.end();
// 基于注解的bean定义扫描器
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
这里AnnotationConfigApplicationContext有两个属性,bean定义读取器和扫描器。
private final AnnotatedBeanDefinitionReader reader;
private final ClassPathBeanDefinitionScanner scanner;
在构造器中开始初始化。
2.1 初始化AnnotatedBeanDefinitionReader
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {
this(registry, getOrCreateEnvironment(registry));
}
这里的BeanDefinitionRegistry是AnnotationConfigApplicationContext实例。因为AnnotationConfigApplicationContext实现了BeanDefinitionRegistry接口。这里的构造器也是门面方法。真正调用的是如下的构造器。
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
//TODO 省略断言
this.registry = registry;
this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
}
这里的conditionEvaluator是条件计算器。什么条件呢。按照一定的条件进行判断,需要注入的Bean满足给定条件才可以注入到Spring IOC容器中。一般使用@Conditional注解。而使用该注解需要实现Condition接口,并重写方法来自定义match规则。conditionEvaluator 的实例化完成之后,存在五个引用。分别是读取到的:
- registry=AnnotationConfigApplicationContext
- beanFactory=DefaultListableBeanFactory
- environment=StandardEnvironment
- 资源加载器
- 类加载器
第三行代码:AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);作用是注册注解配置处理器。在给定的注册表中注册所有相关的注解后处理程序。也就是说注解配置读取完成之后然后根据注解上下文AnnotationConfigApplicationContext的情况进行之后的配置。称之为后处理器。具体的实现在AnnotationConfigUtils类里面;
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
BeanDefinitionRegistry registry, @Nullable Object source) {
DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
if (beanFactory != null) {
if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
//设置beanFactory的依赖关系
beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
}
if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
//设置设置beanFactory的自动解析程序
beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
}
}
Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);
//在Set集合中添加一系列内部的BeanDefinitionHolder.
//BeanDefinitionHolder 主要持有 BeanDefinition的名称和别名
//BeanDefinition描述bean实例的信息。如:bean的作用域、bean是否懒加载、bean的角色,bean的属性信息等。
//bean的角色 role=0 用户使用 role=1内部bean,但是可以通过aware接口获取 role=2完全IOC容器内部。下面添加的bean全部是内部使用
if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
//添加ConfigurationClassPostProcessor 配置类后处理器
}
if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
//添加AutowiredAnnotationBeanPostProcessor 自动注解bean后处理器
}
// 检查 JSR-250、JPA 支持 省略.......
if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {
//添加EventListenerMethodProcessor 事件方法处理器
}
if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {
//添加DefaultEventListenerFactory 默认事件功工厂处理器
}
return beanDefs;
}
registerAnnotationConfigProcessors注册注解配置处理器做了如下几件事:
- 根据传入的注册表registry获取beanFactory,这里的注册表其实就是spring的上下文实例,也就是IOC容器。beanFactory设置依赖关系和自动解析程序。
- 添加一系列处理器。设置角色role=2.全部是IOC容器内部使用。
至此完成了注解bean定义读取器的初始化。
2.2 初始化ClassPathBeanDefinitionScanner
调用自身的构造器:
public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry) {
this(registry, true);
}
这是个门面方法:
public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters) {
this(registry, useDefaultFilters, getOrCreateEnvironment(registry));
}
最终在构造器下实现:
public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters,
Environment environment, @Nullable ResourceLoader resourceLoader) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
this.registry = registry;
if (useDefaultFilters) {
//注册默认的过滤器
registerDefaultFilters();
}
setEnvironment(environment);
setResourceLoader(resourceLoader);
}
注册默认过滤器:
@SuppressWarnings("unchecked")
protected void registerDefaultFilters() {
this.includeFilters.add(new AnnotationTypeFilter(Component.class));
ClassLoader cl = ClassPathScanningCandidateComponentProvider.class.getClassLoader();
try {
this.includeFilters.add(new AnnotationTypeFilter(
((Class<? extends Annotation>) ClassUtils.forName("javax.annotation.ManagedBean", cl)), false));
logger.trace("JSR-250 'javax.annotation.ManagedBean' found and supported for component scanning");
}
catch (ClassNotFoundException ex) {
// JSR-250 1.1 API (as included in Java EE 6) not available - simply skip.
}
try {
this.includeFilters.add(new AnnotationTypeFilter(
((Class<? extends Annotation>) ClassUtils.forName("javax.inject.Named", cl)), false));
logger.trace("JSR-330 'javax.inject.Named' annotation found and supported for component scanning");
}
catch (ClassNotFoundException ex) {
// JSR-330 API not available - simply skip.
}
}
ClassPathBeanDefinitionScanner继承ClassPathScanningCandidateComponentProvider。在注册过滤器的实现中。调用父类的方法registerDefaultFilters()。过滤的注解包括:@Component、@Repository、@Service、@Controller以及Java EE 6的ManagedBean和Named等注解。然后添加到List集合中。也就是说扫描器可以扫描那些注解配置。
这里包括添加