AnnotationConfigApplicationContext
创建AnnotationConfigApplicationContext
- 构造传入注解配置类,一步式解析 扫描 创建spring 容器
AnnotationConfigApplicationContext context
=new AnnotationConfigApplicationContext(AppConfig.class);
这种方式最简单,但不能预先添加自己的BeanFactoryPostProcessor到容器中优先于Spring内置的processor处理
如果有自定义的BeanDefinitionRegistryPostProcessor,会在spring内置处理器执行后以下阶段执行,通过beanDefinitionNames中取
// Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
boolean reiterate = true;
while (reiterate) {
reiterate = false;
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
...
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
...
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, ...
}
-
无参构造,逐步初始化
不需要将BeanRegistryPostProcessor注册为bean时,可手动注册自定义的BeanRegistryPostProcessor后再,这时会优先执行自定义的processor
AnnotationConfigApplicationContext ctx =new AnnotationConfigApplicationContext(); //在invokeBeanFactoryPostProcessor时,取内部后置处理器可以取到 ctx.addBeanFactoryPostProcessor(new CustomBeanRegistryPostProcessor()); ctx.register(AppConfig.class); ctx.refresh();
register/scan
为容器中定义bean 寻找方式
-
传入注解类:AnnotatedBeanDefinitionReader先将该配置类封装为AnnotatedGenericBeanDefinition并通过registry注册该beanDefinition到容器中,在ConfigurationClassPostProcessor处理时会通过ConfigurationClassParser的doProcessConfigurationClass
protected final SourceClass doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass) throws IOException { processMemberClasses(configClass, sourceClass); ... Set<BeanDefinitionHolder> scannedBeanDefinitions = this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName()); ... }
其中由ComponentScanAnnotationParser parse解析,里面再通过ClassPathBeanDefinitionScanner去扫描解析获得BeanDefinitionHolder,所扫面出来带注解的类将以ScannedGenericBeanDefinition形式存在beanFactory
public Set<BeanDefinitionHolder> parse(AnnotationAttributes componentScan, final String declaringClass)