- AnnotationConfigRegistry——注解配置注册表。用于注解配置应用上下文的通用接口,拥有一个注册配置类和扫描配置类的方法。
3.2 构造函数
//默认构造函数,初始化一个空容器,容器不包含任何 Bean 信息,需要在稍后通过调用其register()
//方法注册配置类,并调用refresh()方法刷新容器,触发容器对注解Bean的载入、解析和注册过程
public AnnotationConfigApplicationContext() {
this.reader = new AnnotatedBeanDefinitionReader(this);
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
public AnnotationConfigApplicationContext(DefaultListableBeanFactory beanFactory) {
super(beanFactory);
this.reader = new AnnotatedBeanDefinitionReader(this);
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
//最常用的构造函数,通过将涉及到的配置类传递给该构造函数,以实现将相应配置类中的Bean自动注册到容器中
public AnnotationConfigApplicationContext(Class<?>… annotatedClasses) {
//调用无参构造函数,初始化AnnotatedBeanDefinitionReader 和 ClassPathBeanDefinitionScanner
this();
register(annotatedClasses);
refresh();
}
//该构造函数会自动扫描以给定的包及其子包下的所有类,并自动识别所有的Spring Bean,将其注册到容器中
public AnnotationConfigApplicationContext(String… basePackages) {
//初始化ClassPathBeanDefinitionScanner和AnnotatedBeanDefinitionReader
this();//step1
//扫描包、注册bean
scan(basePackages);//step2
refresh();//step3
}
主要属性:
-
AnnotatedBeanDefinitionReader——BeanDefinition解析器用来解析带注解的bean
-
ClassPathBeanDefinitionScanner——bean的扫描器 用来扫描类
-
注册解析传入的配置类(使用类配置的方式进行解析)
-
调用容器的refresh方法初始化容器
这里我们用的是最后一种构造函数,即传入一个包路径。
3.3 IoC 之 构造函数初始化
首先看step1,调用了本类的无参构造函数:
public AnnotationConfigApplicationContext() {
this.reader = new AnnotatedBeanDefinitionReader(this);
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
然后初始化AnnotatedBeanDefinitionReader和ClassPathBeanDefinitionScanner
我们来看下ClassPathBeanDefinitionScanner的构造函数
public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry) {
this(registry, true);
}
继续跟踪下去,最后调用的是这个方法:
public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters,
Environment environment, @Nullable ResourceLoader resourceLoader) {
Assert.notNull(registry, "BeanDefinitionRegistry must
《一线大厂Java面试题解析+后端开发学习笔记+最新架构讲解视频+实战项目源码讲义》
【docs.qq.com/doc/DSmxTbFJ1cmN1R2dB】 完整内容开源分享
not be null");
//为容器设置加载Bean定义的注册器
this.registry = registry;
//是否使用默认过滤规则
if (useDefaultFilters) {
registerDefaultFilters();
}
//设置环境
setEnvironment(environment);
//为容器设置资源加载器
setResourceLoader(resourceLoader);
}
这里面最主要的是registerDefaultFilters()方法,初始化spring扫描默认过滤规则,对应@ComponentScan注解,如果没有自定义规则,就初始化默认过滤规则。
这里调用的是ClassPathScanningCandidateComponentProvider类中的registerDefaultFilters()方法:
//向容器注册过滤规则
@SuppressWarnings(“unchecked”)
protected void registerDefaultFilters() {
//向要包含的过滤规则中添加@Component注解类
//@Service和@Controller都是Component,因为这些注解都添加了@Component注解
this.includeFilters.add(new AnnotationTypeFilter(Component.class));
//获取当前类的类加载器
ClassLoader cl = ClassPathScanningCandidateComponentProvider.class.getClassLoader();
try {
//向要包含的过滤规则添加JavaEE6的@ManagedBean注解
this.includeFilters.add(new AnnotationTypeFilter(