Spring配置Bean加载和SpringBoot自动加载之间的关系
1.ConfigurationClassPostProcessor 的注入和调用
Springboot启动过程
1.context = createApplicationContext();
1.1 return this.applicationContextFactory.create(this.webApplicationType);
2.return new AnnotationConfigServletWebServerApplicationContext();
3.this.reader = new AnnotatedBeanDefinitionReader(this);
4.this(registry, getOrCreateEnvironment(registry));
5.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);
/**
* 这步为容器注入一个名为
* org.springframework.context.annotation.internalConfigurationAnnotationProcessor
* 类型为ConfigurationClassPostProcessor.class的bean
**/
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
}
ConfigurationClassPostProcessor继承自BeanDefinitionRegistryPostProcessor
Spring容器启动过程中AbstractApplicationContext.invokeBeanFactoryPostProcessors(beanFactory);
因为容器refresh方法之前注册了ConfigurationClassPostProcessor,这里调用BeanDefinitionRegistryPostProcessor后置处理器的接口实现
分两步1.解析配置类 2.处理deferImportSelector
这里对标记传入方法的sourceClass类进行注解解析
其中@ComponentScan会递归调用ConfigurationClassParser.parse方法
代码层面理解就是扫到的配置类上面也可能标注如@Import注解
解析@Import注解之前 递归调用获取importCandidates
一个AutoConfigurationPackages.Registrar.class
一个AutoConfigurationImportSelector.class
对应@Import注解Value的三种Value解析
public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware,
ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered
AutoConfigurationImportSelector会被放入deferredImportSelectorHandler之后处理
2.SpringBoot自动加载
上图grouping.getImports()内部调用过程
1.grouping.getImports();
2.this.group.process(deferredImport.getConfigurationClass().getMetadata(),deferredImport.getImportSelector());
//内部调用spring.loaderfactories方法加载
3.AutoConfigurationEntry autoConfigurationEntry = ((AutoConfigurationImportSelector) deferredImportSelector).getAutoConfigurationEntry(annotationMetadata);
this.autoConfigurationEntries.add(autoConfigurationEntry);//将spring.factories结果封装起来
上图返回spring.factories集合中遍历AutoConfig***类
在放入同样解析@Import注解的processImports方法中处理(spring.factories中的注解都是作为普通Configuration放入容器)
至此自定义和springboot自动配置的Config加载完成
3.扩展
1.其他后置处理器BeanPostProcessor实现有
BeanValidationPostProcessor
|- JSR-303
AnnotationAwareAspectJAutoProxyCreator
|- AOP 实现接口上层是SmartInstantiationAwareBeanPostProcessor
ConfigurationPropertiesBindingPostProcessor
|-解析@ConfigurationProperties注解
2.DeferredImportSelector接口延后了@Import注解加载的顺序 如晚于当前Config类其他注解之后生效;默认ImportSelector和其他注解一起生效
TODO
1.ConfigurationClassPostProcessor中的BeanFactoryPostProcessor实现中有一行
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
int factoryId = System.identityHashCode(beanFactory);
if (this.factoriesPostProcessed.contains(factoryId)) {
throw new IllegalStateException(
"postProcessBeanFactory already called on this post-processor against " + beanFactory);
}
this.factoriesPostProcessed.add(factoryId);
if (!this.registriesPostProcessed.contains(factoryId)) {
// BeanDefinitionRegistryPostProcessor hook apparently not supported...
// Simply call processConfigurationClasses lazily at this point then.
processConfigBeanDefinitions((BeanDefinitionRegistry) beanFactory);
}
//todo CGLIB代理 貌似记得SPRING的confg确实都是代理对象 待验证?
enhanceConfigurationClasses(beanFactory);
beanFactory.addBeanPostProcessor(new ImportAwareBeanPostProcessor(beanFactory));
}
- ConfigurationClassParser中的ImportStack
processImports方法中有这样三个操作 数据结构操作 todo目的?
private final ImportStack importStack = new ImportStack();
this.importStack.push(configClass);
this.importStack.registerImport(currentSourceClass.getMetadata(), candidate.getMetadata().getClassName());
this.importStack.pop();
关键词:Spring后置处理器,@Import注解,Springboot-autoconfig