01导入配置类和用户自定义添加db的ImportBeanDefinitionRegistrar

===============================
--- @Import(AutoConfigurationImportSelector.class)
只要是 @Import + DeferredImportSelector实现类都可以注入到dbregistry(可以仿照springboot的AutoConfigurationImportSelector的写法)

ConfigurationClassParser

ConfigurationClassParser parser = new ConfigurationClassParser(
this.metadataReaderFactory, this.problemReporter, this.environment,
this.resourceLoader, this.componentScanBeanNameGenerator, registry);
parser也注入了registry,但是此时还没有注入到registry

-processDeferredImportSelectors();
AutoConfigurationImportSelector实现了DeferredImportSelector
拿到所有实现了DeferredImportSelector接口的实现类
遍历deferredImports.for()

getImports() 所有DeferredImportSelector的实现类:-->调用AutoConfigurationImportSelector拿到这个importSelector的导入的配置类
.forEach() 所有自动配置类

getConfigurationClasses()从parser中获取到刚才扫描的自动配置类

AutoConfigurationImportSelector

List getCandidateConfigurations(AnnotationMetadata metadata,
AnnotationAttributes attributes)
获取所有配置类名

ConfigurationClassPostProcessor

parser.parse(candidates);解析实现类

parser.getConfigurationClasses()

this.reader.loadBeanDefinitions(configClasses);

ConfigurationClassBeanDefinitionReader

loadBeanDefinitions(configClasses){...}
将configClasses列表注入到registry变成bd

for (ConfigurationClass configClass : configurationModel) {}
loadBeanDefinitionsForConfigurationClass(configClass, trackedConditionEvaluator);

loadBeanDefinitionsForConfigurationClass(ConfigurationClass configClass,TrackedConditionEvaluator trackedConditionEvaluator) {...}

//普通的类,通过loadBeanDefinitionsFromImportedResources方法将其bean定义注册在spring环境
loadBeanDefinitionsFromImportedResources(configClass.getImportedResources());

===============================
ImportBeanDefinitionRegistrar接口的

---@Import注解+实现ImportBeanDefinitionRegistrar类

ConfigurationClassPostProcessor
|
ConfigurationClassParser
|
ConfigurationClassBeanDefinitionReader

ConfigurationClassParser:

拿到所有配置类,包括sb的spring.factories的配置类,@Component/@Service等Component

ConfigurationClassPostProcessor:

processConfigBeanDefinitions

ConfigurationClassBeanDefinitionReader:ccpp调用它。

loadBeanDefinitions(Set configurationModel) 所有的ConfigurationClass类,如果这个类有@Import()还会注入@Import的类作为db进入到dbregistry。如main方法所在类FeignApplication的@EnableFeignClients->@Import(FeignClientsRegistrar.class)。而sb的扫描的@Import与这里的是不同的,sb是在parser类的parse就调用了processDeferredImportSelectors()方法去做spi,扫描configuration

-loadBeanDefinitionsFromRegistrars(configClass.getImportBeanDefinitionRegistrars());调用@Import里的逻辑。比如feign的注入,mybatis-spring的扫描,springboot的AutoConfigurationPackages的Registrar
它们都实现了ImportBeanDefinitionRegistrar接口.
javaguide的rpc中的CustomScannerRegistrar也实现了ImportBeanDefinitionRegistrar接口,然后把scanner放CustomScannerRegistrar进去执行,
也就是说:只要一个@Import注解+实现ImportBeanDefinitionRegistrar类,就可以把自定义逻辑的bd注入到bdregistry中。

loadBeanDefinitionsForConfigurationClass(ConfigurationClass configClass,TrackedConditionEvaluator trackedConditionEvaluator) {...}

loadBeanDefinitionsForConfigurationClass(configClass, trackedConditionEvaluator);

loadBeanDefinitionsFromRegistrars(configClass.getImportBeanDefinitionRegistrars());
//实现了ImportBeanDefinitionRegistrar接口的实例,会在loadBeanDefinitionsFromRegistrars方法中执行其registerBeanDefinitions方法

FeignClientsRegistrar

ConfigurationClassPostProcessor

this.reader.loadBeanDefinitions(configClasses);
所有的ConfigurationClass类

原文地址:https://www.cnblogs.com/kltsee/p/15126403.html