Spring-AnnotationConfigApplicationContext
1. 简介
使用 AnnotationConfigApplicationContext 创建 Spring 应用上下文时,需要指定一个或多个配置类。,开发者可以直接在 Java 类中使用注解如 @Configuration、@Bean 等来声明和配置 Bean。
AnnotationConfigApplicationContext 属于 Spring 的 Java 配置支持模块,用于以纯 Java 注解的方式来替代 XML 配置文件来创建和管理 Spring 容器上下文。
-
AnnotationConfigApplicationContext
-
ClassPathXmlApplicationContext
-
FileSystemXmlApplicationContext
2. 构造方法
-
public AnnotationConfigApplicationContext()
无参构造
//就是初始化两个全局变量 public AnnotationConfigApplicationContext() { this.reader = new AnnotatedBeanDefinitionReader(this); this.scanner = new ClassPathBeanDefinitionScanner(this); }
private static void test1(){ AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); context.register(TestBean.class, DogBean.class); context.refresh(); TestBean bean = context.getBean(TestBean.class); bean.helloSpring(); }
无参构造,需要手动调用 register() 或者 scan() 和 refresh() 方法
-
public AnnotationConfigApplicationContext(DefaultListableBeanFactory beanFactory)
以 beanFactory 为参数
public AnnotationConfigApplicationContext(DefaultListableBeanFactory beanFactory) { super(beanFactory); this.reader = new AnnotatedBeanDefinitionReader(this); this.scanner = new ClassPathBeanDefinitionScanner(this); }
private static void test2(){ AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(new DefaultListableBeanFactory()); context.register(TestBean.class, DogBean.class); context.refresh(); TestBean bean = context.getBean(TestBean.class); bean.helloSpring(); }
相比无参构造,多了一个 super(beanFactory),看看 super(beanFactory) 做了什么事情:
GenericApplicationContext.super()
public GenericApplicationContext() { this.beanFactory = new DefaultListableBeanFactory(); } /** * Create a new GenericApplicationContext with the given DefaultListableBeanFactory. * @param beanFactory the DefaultListableBeanFactory instance to use for this context * @see #registerBeanDefinition * @see #refresh */ public GenericApplicationContext(DefaultListableBeanFactory beanFactory) { Assert.notNull(beanFactory, "BeanFactory must not be null"); this.beanFactory = beanFactory; }
可以发现,是在父类将
this.beanFactory
赋值,不用这个构造就是直接 new 一个默认的。 -
public AnnotationConfigApplicationContext(Class<?>... componentClasses)
以多个 class 为参数
public AnnotationConfigApplicationContext(Class<?>... componentClasses) { this(); register(componentClasses); refresh(); }
private static void test3(){ ApplicationContext context = new AnnotationConfigApplicationContext(TestBean.class, DogBean.class); TestBean bean = context.getBean(TestBean.class); bean.helloSpring(); DogBean dog = context.getBean(DogBean.class); dog.say(); }
相当于无参构造 + register() + refresh(),这里参数 TestBean,可以是普通的 pojo 类,无需有 @Component 注解
-
public AnnotationConfigApplicationContext(String... basePackages)
以多个包路径为参数
public AnnotationConfigApplicationContext(String... basePackages) { this(); scan(basePackages); refresh(); }
private static void test4(){ ApplicationContext context = new AnnotationConfigApplicationContext("org.springframework.component"); TestBean bean = context.getBean(TestBean.class); bean.helloSpring(); DogBean dog = context.getBean(DogBean.class); dog.say(); }
相当于无参构造 + scan() + refresh()
3. 过程解析
-
- super(beanFactory) 父类的构造方法
-
- new AnnotationConfigApplicationContext() 初始化容器
-
- register() todo 注册 benn 类
-
- scan() 扫描类路径
-
- refresh() 刷新容器
1. 父类构造方法
执行子类构造方法时,会先执行父类构造方法,也就是this()方法的执行会先去执行父类的构造方法,那么就先从父类构造方法看起
AnnotationConfigApplicationContext继承自GenericApplicationContext
public GenericApplicationContext() {
/**
* 初始化一个工厂类,用于创建bean对象
* @reviewer wangcongming
*/
this.beanFactory = new DefaultListableBeanFactory();
}
public GenericApplicationContext(DefaultListableBeanFactory beanFactory) {
Assert.notNull(beanFactory, "BeanFactory must not be null");
//直接赋值工厂类
this.beanFactory = beanFactory;
}
初始化了一个工厂类 DefaultListableBeanFactory,几个重要属性:
/**
* 用于排序
* @reviewer wangcongming
*/
@Nullable
private Comparator<Object> dependencyComparator;
/**
* 自动注入解析器
* @reviewer wangcongming
*/
private AutowireCandidateResolver autowireCandidateResolver = new SimpleAutowireCandidateResolver();
/**
* 依赖
* @reviewer wangcongming
*/
private final Map<Class<?>, Object> resolvableDependencies = new ConcurrentHashMap<>(16);
/**
* spring核心,用于存放BeanDefinition(描述bean的类)
* @reviewer wangcongming
*/
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);
/**
* class与bean name映射关系
* @reviewer wangcongming
*/
private final Map<Class<?>, String[]> allBeanNamesByType = new ConcurrentHashMap<>(64);
/**
* 单例 class与bean name映射关系
* @reviewer wangcongming
*/
private final Map<Class<?>, String[]> singletonBeanNamesByType = new ConcurrentHashMap<>(64);
/**
* 用于存放bean name
* @reviewer wangcongming
*/
private volatile List<String> beanDefinitionNames = new ArrayList<>(256);
总之这一步的作用就是,AnnotationConfigApplicationContext
示例持有一个 DefaultListableBeanFactory
实例
2. AnnotationConfigApplicationContext 初始行
public AnnotationConfigApplicationContext() {
/**
* 初始化一个AnnotatedBeanDefinition读取器,用于读取被注解标注的bean,
* 读取的信息存放入AnnotatedBeanDefinition
*/
this.reader = new AnnotatedBeanDefinitionReader(this);
/**
* 初始化一个扫描器,用于扫描类或者包下的所有类,将被注解标注的bean生成对应的AnnotatedBeanDefinition
*/
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
无参构造中只做了两件事,初始化一个读取器(AnnotatedBeanDefinitionReader)和一个扫描器(ClassPathBeanDefinitionScanner)
-
- 先看
new AnnotatedBeanDefinitionReader(this)
:
AnnotatedBeanDefinitionReader 类构造方法 public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) { this(registry, getOrCreateEnvironment(registry)); } 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); }
AnnotationConfigUtils.registerAnnotationConfigProcessors() 最终调用: public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors( BeanDefinitionRegistry registry, @Nullable Object source) { /** * 从registry中获取DefaultListableBeanFactory * */ DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry); if (beanFactory != null) { /** * 初始化一个比较器 * */ if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) { beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE); } /** * 像是 Autowire 解析器 * */ if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) { beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver()); } } /** * 创建一个 Set,用于加入一些spring自己定义的bean,以便于后面初始化使用,完成一些功能。实际上在这里是没用用的,因为这个 set 返回了之后没用 */ Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8); /** * ConfigurationClassPostProcessor用于读取配置类的 */ if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) { //创建一个 BeanDefinition RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class); def.setSource(source); /** * new AnnotationConfigApplicationContext 这个分析中,其实用 registerPostProcessor 起作用的,beanDefs.add 没用 */ beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)); } /** * AutowiredAnnotationBeanPostProcessor 用于处理依赖注入的 * */ if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) { RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class); def.setSource(source); beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)); } /** * 用于处理JSR-250支持 * */ // Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor. if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) { RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class); def.setSource(source); beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)); } /** * 用于支持jpa的 * */ // Check for JPA support, and if present add the PersistenceAnnotationBeanPostProcessor. if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) { RootBeanDefinition def = new RootBeanDefinition(); try { def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, AnnotationConfigUtils.class.getClassLoader())); } catch (ClassNotFoundException ex) { throw new IllegalStateException( "Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex); } def.setSource(source); beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)); } /** * 像是事件监听器 * */ if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) { RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class); def.setSource(source); beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME)); } /** * 像是事件监听工厂 * */ if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) { RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class); def.setSource(source); beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME)); } return beanDefs; }
(1)初始化 DependencyComparator 比较器
(2)应该是 Autowired 解析器
(3)注册了一些默认的 BeanDefinition 到 AnnotationConfigApplicationContext 持有的 registry 中。AnnotationConfigUtils.registerPostProcessor() 注册 beanDefinition private static BeanDefinitionHolder registerPostProcessor( BeanDefinitionRegistry registry, RootBeanDefinition definition, String beanName) { definition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); //通过 AnnotationConfigApplicationContext 的方法注入 beanDefinition registry.registerBeanDefinition(beanName, definition); return new BeanDefinitionHolder(definition, beanName); }
DefaultListableBeanFactory.registerBeanDefinition():将 beanDefinition 注册到自己的 beanDefinitionMap 中 /** * this.beanDefinitionMap.put(beanName, beanDefinition) * this.beanDefinitionNames.add(beanName) * */ @Override public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws BeanDefinitionStoreException { Assert.hasText(beanName, "Bean name must not be empty"); Assert.notNull(beanDefinition, "BeanDefinition must not be null"); if (beanDefinition instanceof AbstractBeanDefinition) { try { ((AbstractBeanDefinition) beanDefinition).validate(); } catch (BeanDefinitionValidationException ex) { throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName, "Validation of bean definition failed", ex); } } BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName); if (existingDefinition != null) { if (!isAllowBeanDefinitionOverriding()) { throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition); } else if (existingDefinition.getRole() < beanDefinition.getRole()) { // e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE if (logger.isInfoEnabled()) { logger.info("Overriding user-defined bean definition for bean '" + beanName + "' with a framework-generated bean definition: replacing [" + existingDefinition + "] with [" + beanDefinition + "]"); } } else if (!beanDefinition.equals(existingDefinition)) { if (logger.isDebugEnabled()) { logger.debug("Overriding bean definition for bean '" + beanName + "' with a different definition: replacing [" + existingDefinition + "] with [" + beanDefinition + "]"); } } else { if (logger.isTraceEnabled()) { logger.trace("Overriding bean definition for bean '" + beanName + "' with an equivalent definition: replacing [" + existingDefinition + "] with [" + beanDefinition + "]"); } } this.beanDefinitionMap.put(beanName, beanDefinition); } else { if (hasBeanCreationStarted()) { // Cannot modify startup-time collection elements anymore (for stable iteration) synchronized (this.beanDefinitionMap) { this.beanDefinitionMap.put(beanName, beanDefinition); List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1); updatedDefinitions.addAll(this.beanDefinitionNames); updatedDefinitions.add(beanName); this.beanDefinitionNames = updatedDefinitions; removeManualSingletonName(beanName); } } else { // Still in startup registration phase this.beanDefinitionMap.put(beanName, beanDefinition); this.beanDefinitionNames.add(beanName); removeManualSingletonName(beanName); } this.frozenBeanDefinitionNames = null; } if (existingDefinition != null || containsSingleton(beanName)) { resetBeanDefinition(beanName); } else if (isConfigurationFrozen()) { clearByTypeCache(); } }
- 先看
-
- 再看
new ClassPathBeanDefinitionScanner(this)
- 再看