AnnotationConfigApplicationContext
前言
AnnotationConfigApplicationContext 和 ClassPathXmlApplicationContext 与 FileSystemXmlApplicationContext 类似都是抽象类 AbstractApplicationContext 的子类,最终都调用父类的 refresh 方法开始 bean工厂的初始化等一系列操作,不同的是 AnnotationConfigApplicationContext 是通过注解进行bean扫描的,而另外两个是通过xml进行bean注册的,接下来我们看看 AnnotationConfigApplicationContext 是怎么扫描bean的,附结构图
使用说明
- 测试bean
import org.springframework.stereotype.Component; @Component public class TestBean { public String test() { return "test"; } } - 启动类
import org.springframework.context.annotation.AnnotationConfigApplicationContext; public class DemoApplication { public static void main(String[] args) { AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext("com.example.demo"); TestBean testBean = annotationConfigApplicationContext.getBean(TestBean.class); System.out.println(testBean.test()); } }
源码解析
我们通过创建 AnnotationConfigApplicationContext 类并传入项目包名即可获取到这个包及子包下的bean了,我们看一下 的构造器方法
-
构造器
public AnnotationConfigApplicationContext(String... basePackages) { this(); scan(basePackages); refresh(); }主要分三部分,1、调用无参构造器,2、根据传入的包名进行bean扫描,3、调用父类的refresh方法,这里我们主要关注1、2两步
-
无参构造器
public AnnotationConfigApplicationContext() { // 该类用于传入指定bean的类的时候使用,会直接进行beanDefinition注册 this.reader = new AnnotatedBeanDefinitionReader(this); // 该类用于通过类路径进行扫描并将符合的bean进行beanDefinition注册 this.scanner = new ClassPathBeanDefinitionScanner(this); }通过指定包名创建 AnnotationConfigApplicationContext 类时就是通过 scanner 进行扫描的,注意这里会传入 this 参数,不管是直接指定bean的类进行注册还是扫描注册,实际上是注册到类 DefaultListableBeanFactory 的 beanDefinitionMap(重要) 参数上,参数类型为
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);
而 DefaultListableBeanFactory 是 this 的父类 GenericApplicationContext 进行初始化的,我们知道,子类初始化时会先初始化父类public GenericApplicationContext() { this.beanFactory = new DefaultListableBeanFactory(); } -
扫描bean
@Override public void scan(String... basePackages) { Assert.notEmpty(basePackages, "At least one base package must be specified"); // 委托给 scanner 进行扫描 this.scanner.scan(basePackages); }public int scan(String... basePackages) { // 1.先获取已注册的beanDefinition数量 int beanCountAtScanStart = this.registry.getBeanDefinitionCount()


最低0.47元/天 解锁文章
1275

被折叠的 条评论
为什么被折叠?



