共计 21568 个字符,预计需要花费 54 分钟才能阅读完成。
@Import 是一个能让类生成为 Spring Bean 的注解。
@Import 注解它次要是配合 ImportSelector 和 @ImportBeanDefinitionRegistrar 的子类,或者一般的 Java Bean 类应用。
@Import 注解源码
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Import {
/**
* 须要引入的类,通常是 @ImportSelector , @ImportBeanDefinitionRegistrar 的子类;或者是当成其余一般的 Bean 来应用。*/
Class<?>[] value();
}
一般 Bean 用法
在 @Import 注解导入一般 Bean 时,这个一般 Bean 必须要有无参构造方法,不然的话会报错。
例子
@SpringBootTest
@Import(ImportNormalBeanTest.NormalBeanClass.class)
public class ImportNormalBeanTest {
@Autowired
ApplicationContext ctx;
@Test
void testNormalBean(){NormalBeanClass bean = ctx.getBean(NormalBeanClass.class);
System.out.println(bean);
}
public static class NormalBeanClass{
@Override
public String toString() {return "normal bean";}
}
}
测试后果
normal bean
ImportSelector
ImportSelector 接口通过自定义的算法,去抉择要引入的 Spring Bean。如果 ImportSelector 的子类实现了以下的接口,它会依照接口的程序先调用这些接口的办法,再去调用 ImportSelector 的办法:
- BeanClassLoaderAware
- BeanFactoryAware
- EnvironmentAware
- ResourceLoaderAware
ImportSelector 源码
public interface ImportSelector {// 返回要加载的 class 全限定名,能够通过 Class.getName() 来获取
String[] selectImports(AnnotationMetadata importingClassMetadata);
// 是否过滤掉该 ImportSelector
// Predicate 返回 true 示意过滤掉,false 或者 null 示意不过滤
@Nullable
default Predicate<String> getExclusionFilter() {return null;}
}
例子
@SpringBootTest
@Import(ImportSelectorTest.TestBeanImportSelector.class)
public class ImportSelectorTest {
@Autowired
private ApplicationContext ctx;
@Test
void test(){final TestBeanClass bean = ctx.getBean(TestBeanClass.class);
System.out.println(bean);
}
// 自定义一个 ImportSelector , 并且实现了 4 个 aware 的接口,用于验证调用程序
public static class TestBeanImportSelector implements ImportSelector,
EnvironmentAware, BeanFactoryAware, BeanClassLoaderAware, ResourceLoaderAware {
@Override
public String[] selectImports(AnnotationMetadata importingClassMetadata) {System.out.println("invoke selectImports method");
return new String[]{TestBeanClass.class.getName()};
}
@Override
public void setBeanClassLoader(ClassLoader classLoader) {System.out.println("BeanClassLoader set");
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {System.out.println("beanFactory set");
}
@Override
public void setEnvironment(Environment environment) {System.out.println("environment set");
}
@Override
public void setResourceLoader(ResourceLoader resourceLoader) {System.out.println("resourceLoader set");
}
}
public static class TestBeanClass{
@Override
public String toString() {return "test bean";}
}
}
运行后果
BeanClassLoader set
beanFactory set
environment set
resourceLoader set
invoke selectImports method
test bean
配合自定义注解应用
ImportSelector 还能配合自定义注解,来决定须要引入的 Bean。
例子
/**
* 这里同时引入 TestBeanClassAnnotation 和 AnotherTestBeanClassAnnotation 这 2 个注解
* 那么会将 TestBeanClass 和 AnotherTestBeanClass 对应的 Bean 加到到 Spring 容器中去
* 能够只应用其中一个注解,以只加载注解关联的 Bean
*/
@SpringBootTest
@ImportSelectorTest.TestBeanClassAnnotation
@ImportSelectorTest.AnotherTestBeanClassAnnotation
public class ImportSelectorTest {
@Autowired
private ApplicationContext ctx;
@Test
void test(){System.out.println(ctx.getBean(TestBeanClass.class));
System.out.println(ctx.getBean(AnotherTestBeanClass.class));
}
/**
* 示意只引入 TestBeanClass 的 Bean
* 并且通过 @Import 注解来引入 TestBeanImportSelector
*/
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Target(ElementType.TYPE)
@Import(ImportSelectorTest.TestBeanImportSelector.class)
public @interface TestBeanClassAnnotation{ }
/**
* 示意只引入 AnotherTestBeanClass 的 Bean
* 并且通过 @Import 注解来引入 TestBeanImportSelector
*/
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Target(ElementType.TYPE)
@Import(ImportSelectorTest.TestBeanImportSelector.class)
public @interface AnotherTestBeanClassAnnotation{ }
// 自定义一个 ImportSelector , 并且实现了 4 个 aware 的接口,用于验证调用程序
public static class TestBeanImportSelector implements ImportSelector,
EnvironmentAware, BeanFactoryAware, BeanClassLoaderAware, ResourceLoaderAware {
@Override
public String[] selectImports(AnnotationMetadata importingClassMetadata) {System.out.println("invoke selectImports method");
List<String> classNameList = new ArrayList<>();
// 获取援用到该 ImportSelector 的注解
Set<String> annotationTypes = importingClassMetadata.getAnnotationTypes();
for (String annotationType : annotationTypes) {if(TestBeanClassAnnotation.class.getName().equals(annotationType)){classNameList.add(TestBeanClass.class.getName());
}else if(AnotherTestBeanClassAnnotation.class.getName().equals(annotationType)){classNameList.add(AnotherTestBeanClass.class.getName());
}
}
return classNameList.toArray(new String[0]);
}
@Override
public void setBeanClassLoader(ClassLoader classLoader) {System.out.println("BeanClassLoader set");
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {System.out.println("beanFactory set");
}
@Override
public void setEnvironment(Environment environment) {System.out.println("environment set");
}
@Override
public void setResourceLoader(ResourceLoader resourceLoader) {System.out.println("resourceLoader set");
}
}
// 要应用到的 Bean 对应的 class
public static class TestBeanClass{
@Override
public String toString() {return "test bean";}
}
public static class AnotherTestBeanClass{
@Override
public String toString(){return "another test bean";}
}
}
输入后果
BeanClassLoader set
beanFactory set
environment set
resourceLoader set
invoke selectImports method
test bean
another test bean
ImportBeanDefinitionRegistrar
ImportBeanDefinitionRegistrar 接口适宜应用在创立 BeanDefinition 的场景,例如 Mybatis-Spring 的 MapperScannerRegistrar ,
就是实现了 ImportBeanDefinitionRegistrar 的 registerBeanDefinitions 办法,来注入 Mapper 接口对应的 BeanDefinition。
ImportBeanDefinitionRegistrar 和 ImportSelector 一样,如果 ImportBeanDefinitionRegistrar 的子类也实现了指定的 Aware 子类,也会依照以下程序来执行:
- BeanClassLoaderAware
- BeanFactoryAware
- EnvironmentAware
- ResourceLoaderAware
ImportBeanDefinitionRegistrar 源码
public interface ImportBeanDefinitionRegistrar {
default void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry,
BeanNameGenerator importBeanNameGenerator) {registerBeanDefinitions(importingClassMetadata, registry);
}
// 利用 BeanDefinitionRegistry 来注册 BeanDefinition,后续 Spring 容器通过 BeanDefinition 来创立 Bean
default void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {}}
例子
@SpringBootTest
@Import(ImportBeanDefinitionRegistrarTest.TestImportBeanDefinitionRegistrar.class)
public class ImportBeanDefinitionRegistrarTest {
@Autowired
private ApplicationContext ctx;
@Test
void test(){System.out.println(ctx.getBean(TestBean.class));
}
public static class TestImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
// 增加 TestBean 对应的 BeanDefinition 到 BeanDefinitionRegistry 中
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(TestBean.class);
AbstractBeanDefinition beanDefinition = builder.getBeanDefinition();
registry.registerBeanDefinition("testBean", beanDefinition);
}
}
public static class TestBean{
@Override
public String toString() {return "test bean";}
}
}
输入后果
test bean
源码解析
在 Spring 初始化容器时,会调用到 AbstractApplicationContext#refresh() 的办法:
AbstractApplicationContext#refresh() 办法
public void refresh() throws BeansException, IllegalStateException {synchronized (this.startupShutdownMonitor) {StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");
prepareRefresh();
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
prepareBeanFactory(beanFactory);
try {postProcessBeanFactory(beanFactory);
StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
// 调用所有注册到的 BeanFactoryPostProcessor
invokeBeanFactoryPostProcessors(beanFactory);
// 疏忽前面局部的代码
}
// 疏忽前面局部的代码
}
}
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
// 实际上调用以下办法来调用所有 BeanFactoryPostProcessor
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
// 疏忽以下办法
}
从下面的源码得悉,实际上调用 PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors()
办法。
PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors() 办法
public static void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {Set<String> processedBeans = new HashSet<>();
if (beanFactory instanceof BeanDefinitionRegistry registry) {
// 存储所有 BeanFactoryPostProcessor
List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
// 存储所有 BeanDefinitionRegistryPostProcessor
List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
// 疏忽中间代码
// 存储以后曾经获取到的 BeanDefinitionRegistryPostProcessor
List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
// 扫描 Beanfactory 曾经加载到的 BeanDefinitionRegistryPostProcessor 的 bean
// 其中会扫描到一个 ConfigurationClassPostProcessor 的 Bean , 它实现了 BeanDefinitionRegistryPostProcessor 接口
// 这个 Bean 通过重写 BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry() 的办法去做解决 @Import 注解的逻辑
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
// 这里会调用曾经获取到的 BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry() 办法,其中曾经蕴含 ConfingurationClassPostProcssor
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
// 疏忽中间代码
}
// 疏忽后续代码
}
// 遍历地调用 postProcessors 参数列表的 postProcessBeanDefinitionRegistry() 办法
private static void invokeBeanDefinitionRegistryPostProcessors(Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors, BeanDefinitionRegistry registry, ApplicationStartup applicationStartup) {for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) {StartupStep postProcessBeanDefRegistry = applicationStartup.start("spring.context.beandef-registry.post-process")
.tag("postProcessor", postProcessor::toString);
// 循环调用 BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry() 办法
postProcessor.postProcessBeanDefinitionRegistry(registry);
postProcessBeanDefRegistry.end();}
}
在 PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors()
中,Spring 加载了 ConfigurationClassPostProcessor 的 Bean 进去。
因为 ConfigurationClassPostProcessor 是 BeanDefinitionRegistryPostProcessor 的子类,故在 invokeBeanDefinitionRegistryPostProcessors
办法中便会调用到 ConfingurationClassPostProcssor#postProcessBeanDefinitionRegistry()
的办法。
ConfingurationClassPostProcssor#postProcessBeanDefinitionRegistry() 办法
// 这里只展现外围的 postProcessBeanDefinitionRegistry() 办法
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
// 疏忽下面局部的代码
// ConfigurationClassPostProcessor 实际上是调用 processConfigBeanDefinitions() 办法来做具体的逻辑
processConfigBeanDefinitions(registry);
}
public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {List<BeanDefinitionHolder> configCandidates = new ArrayList<>();
// 从 BeanDefinitionRegistry 中获取 BeanDefinitionNames 列表
String[] candidateNames = registry.getBeanDefinitionNames();
// 增加 BeanDefinitionNames 列表到 configCandidates 类表中去
for (String beanName : candidateNames) {BeanDefinition beanDef = registry.getBeanDefinition(beanName);
if (beanDef.getAttribute(ConfigurationClassUtils.CONFIGURATION_CLASS_ATTRIBUTE) != null) {if (logger.isDebugEnabled()) {logger.debug("Bean definition has already been processed as a configuration class:" + beanDef);
}
}
else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
}
}
// 如果 configCandidates 列表为空,则完结流程
if (configCandidates.isEmpty()) {return;}
// 如果 BeanDefinition 关联的 class 有 @Order 注解的话,就去排序
configCandidates.sort((bd1, bd2) -> {int i1 = ConfigurationClassUtils.getOrder(bd1.getBeanDefinition());
int i2 = ConfigurationClassUtils.getOrder(bd2.getBeanDefinition());
return Integer.compare(i1, i2);
});
// Detect any custom bean name generation strategy supplied through the enclosing application context
SingletonBeanRegistry sbr = null;
if (registry instanceof SingletonBeanRegistry) {sbr = (SingletonBeanRegistry) registry;
if (!this.localBeanNameGeneratorSet) {BeanNameGenerator generator = (BeanNameGenerator) sbr.getSingleton(AnnotationConfigUtils.CONFIGURATION_BEAN_NAME_GENERATOR);
if (generator != null) {
this.componentScanBeanNameGenerator = generator;
this.importBeanNameGenerator = generator;
}
}
}
if (this.environment == null) {this.environment = new StandardEnvironment();
}
// Parse each @Configuration class
ConfigurationClassParser parser = new ConfigurationClassParser(
this.metadataReaderFactory, this.problemReporter, this.environment,
this.resourceLoader, this.componentScanBeanNameGenerator, registry);
Set<BeanDefinitionHolder> candidates = new LinkedHashSet<>(configCandidates);
Set<ConfigurationClass> alreadyParsed = new HashSet<>(configCandidates.size());
do {StartupStep processConfig = this.applicationStartup.start("spring.context.config-classes.parse");
// 解析 @Import 注解的入口,并将读取到的类增加到 parser.configurationClasses 列表中
parser.parse(candidates);
parser.validate();
// 读取 parser.configurationClasses.keySet()
Set<ConfigurationClass> configClasses = new LinkedHashSet<>(parser.getConfigurationClasses());
// 去掉曾经加载过的 configClasses
configClasses.removeAll(alreadyParsed);
if (this.reader == null) {
this.reader = new ConfigurationClassBeanDefinitionReader(
registry, this.sourceExtractor, this.resourceLoader, this.environment,
this.importBeanNameGenerator, parser.getImportRegistry());
}
// 将 configClasses 转换成 BeanDefinition , 供应前面创立 Bean 的应用
this.reader.loadBeanDefinitions(configClasses);
alreadyParsed.addAll(configClasses);
// 疏忽后续局部代码
}
while (!candidates.isEmpty());
// 疏忽后续局部代码
}
ConfigurationClassPostProcessor#postProcessBeanDefinitionRegistry()
办法实际上是调用了 processConfigBeanDefinitions
办法。他次要做了这些事件:
processConfigBeanDefinitions
先去扫描BeanDefinitionRegistry
保护的BeanDefinitionNames
列表- 通过
BeanDefinitionNames
列表转换成configCandidates
列表 - 对
configCandidates
列表的元素做排序操作 - 通过
ConfigurationClassParser#parse()
办法,去读取configCandidates
列表, 并将configCandidates
列表中有应用到的 @Import 注解的类,调用它们相干的办法。
例如ImportSelector#selectImports()
办法
并且将调用办法后失去的后果,存入到ConfigurationClassParser.configurationClasses
的 map 中去 - 调用
ConfigurationClassBeanDefinitionReader#loadBeanDefinitions
办法,将ConfigurationClassParser.configurationClasses
的 map 内容转换成 BeanDefinition 列表
从下面的流程中,ConfigurationClassParser#parse()
是读取 @Import
注解的要害入口。
ConfigurationClassParser#parse() 办法
public void parse(Set<BeanDefinitionHolder> configCandidates) {for (BeanDefinitionHolder holder : configCandidates) {BeanDefinition bd = holder.getBeanDefinition();
try {// 这里次要是调用了 parse() 办法
if (bd instanceof AnnotatedBeanDefinition) {parse(((AnnotatedBeanDefinition) bd).getMetadata(), holder.getBeanName());
}
else if (bd instanceof AbstractBeanDefinition && ((AbstractBeanDefinition) bd).hasBeanClass()) {parse(((AbstractBeanDefinition) bd).getBeanClass(), holder.getBeanName());
}
else {parse(bd.getBeanClassName(), holder.getBeanName());
}
}
// 疏忽上面的代码
}
this.deferredImportSelectorHandler.process();}
protected final void parse(Class<?> clazz, String beanName) throws IOException {// parse() 办法调用了 processConfigurationClass() 办法
processConfigurationClass(new ConfigurationClass(clazz, beanName), DEFAULT_EXCLUSION_FILTER);
}
protected void processConfigurationClass(ConfigurationClass configClass, Predicate<String> filter) throws IOException {
// 疏忽下面局部的代码
SourceClass sourceClass = asSourceClass(configClass, filter);
do {// 次要是调用 doProcessConfigurationClass() 办法
sourceClass = doProcessConfigurationClass(configClass, sourceClass, filter);
}
while (sourceClass != null);
// 将 doProcessConfigurationClass() 办法批改的 configClass 塞到 configurationClasses 的 Map 中去
this.configurationClasses.put(configClass, configClass);
}
protected final SourceClass doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass, Predicate<String> filter)
throws IOException {if (configClass.getMetadata().isAnnotated(Component.class.getName())) {// Recursively process any member (nested) classes first
processMemberClasses(configClass, sourceClass, filter);
}
// 解析 @PropertySource 的注解
for (AnnotationAttributes propertySource : AnnotationConfigUtils.attributesForRepeatable(sourceClass.getMetadata(), PropertySources.class,
org.springframework.context.annotation.PropertySource.class)) {if (this.propertySourceRegistry != null) {this.propertySourceRegistry.processPropertySource(propertySource);
}
else {logger.info("Ignoring @PropertySource annotation on [" + sourceClass.getMetadata().getClassName() +
"]. Reason: Environment must implement ConfigurableEnvironment");
}
}
// 解析 @ComponentScan 的注解
Set<AnnotationAttributes> componentScans = AnnotationConfigUtils.attributesForRepeatable(sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class);
if (!componentScans.isEmpty() &&
!this.conditionEvaluator.shouldSkip(sourceClass.getMetadata(), ConfigurationPhase.REGISTER_BEAN)) {for (AnnotationAttributes componentScan : componentScans) {
// The config class is annotated with @ComponentScan -> perform the scan immediately
Set<BeanDefinitionHolder> scannedBeanDefinitions =
this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());
// Check the set of scanned definitions for any further config classes and parse recursively if needed
for (BeanDefinitionHolder holder : scannedBeanDefinitions) {BeanDefinition bdCand = holder.getBeanDefinition().getOriginatingBeanDefinition();
if (bdCand == null) {bdCand = holder.getBeanDefinition();
}
if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) {parse(bdCand.getBeanClassName(), holder.getBeanName());
}
}
}
}
// 解析 @Import 注解
processImports(configClass, sourceClass, getImports(sourceClass), filter, true);
// 解析 @ImportResource 注解
AnnotationAttributes importResource =
AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(), ImportResource.class);
if (importResource != null) {String[] resources = importResource.getStringArray("locations");
Class<? extends BeanDefinitionReader> readerClass = importResource.getClass("reader");
for (String resource : resources) {String resolvedResource = this.environment.resolveRequiredPlaceholders(resource);
configClass.addImportedResource(resolvedResource, readerClass);
}
}
// 解析 @Bean 办法
Set<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(sourceClass);
for (MethodMetadata methodMetadata : beanMethods) {configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
}
// 疏忽上面的办法
}
从下面的代码执行流程中,能够看到解析 @Import 注解的是 ConfigurationClassParser#processImports()
办法
ConfigurationClassParser#processImports() 办法
该办法时解析 @Import 注解的外围逻辑:
private void processImports(ConfigurationClass configClass, SourceClass currentSourceClass,
Collection<SourceClass> importCandidates, Predicate<String> exclusionFilter,
boolean checkForCircularImports) {if (importCandidates.isEmpty()) {return;}
if (checkForCircularImports && isChainedImportOnStack(configClass)) {this.problemReporter.error(new CircularImportProblem(configClass, this.importStack));
}
else {this.importStack.push(configClass);
try {for (SourceClass candidate : importCandidates) {
// 解析 ImportSelector 接口
if (candidate.isAssignable(ImportSelector.class)) {
// Candidate class is an ImportSelector -> delegate to it to determine imports
Class<?> candidateClass = candidate.loadClass();
ImportSelector selector = ParserStrategyUtils.instantiateClass(candidateClass, ImportSelector.class,
this.environment, this.resourceLoader, this.registry);
Predicate<String> selectorFilter = selector.getExclusionFilter();
if (selectorFilter != null) {exclusionFilter = exclusionFilter.or(selectorFilter);
}
if (selector instanceof DeferredImportSelector) {this.deferredImportSelectorHandler.handle(configClass, (DeferredImportSelector) selector);
}
else {// 调用 ImportSelector#selectImports() 办法,获取 Bean 对应的 class 名字
String[] importClassNames = selector.selectImports(currentSourceClass.getMetadata());
Collection<SourceClass> importSourceClasses = asSourceClasses(importClassNames, exclusionFilter);
// 将这些获取到的 class 名字递归地调用 processImports() 办法
processImports(configClass, currentSourceClass, importSourceClasses, exclusionFilter, false);
}
}
// 解析 ImportBeanDefinitionRegistrar 接口
else if (candidate.isAssignable(ImportBeanDefinitionRegistrar.class)) {
// Candidate class is an ImportBeanDefinitionRegistrar ->
// delegate to it to register additional bean definitions
Class<?> candidateClass = candidate.loadClass();
ImportBeanDefinitionRegistrar registrar =
ParserStrategyUtils.instantiateClass(candidateClass, ImportBeanDefinitionRegistrar.class,
this.environment, this.resourceLoader, this.registry);
configClass.addImportBeanDefinitionRegistrar(registrar, currentSourceClass.getMetadata());
}
// 解析其余类型,会把它们当作 @Configuration 类来解决
else {
// Candidate class not an ImportSelector or ImportBeanDefinitionRegistrar ->
// process it as an @Configuration class
this.importStack.registerImport(currentSourceClass.getMetadata(), candidate.getMetadata().getClassName());
processConfigurationClass(candidate.asConfigClass(configClass), exclusionFilter);
}
}
}
catch (BeanDefinitionStoreException ex) {throw ex;}
catch (Throwable ex) {
throw new BeanDefinitionStoreException(
"Failed to process import candidates for configuration class [" +
configClass.getMetadata().getClassName() + "]:" + ex.getMessage(), ex);
}
finally {this.importStack.pop();
}
}
}
ConfigurationClassBeanDefinitionReader#loadBeanDefinitions() 办法
当 Spring 加载完了 @Import 注解之后,会通过 ConfigurationClassBeanDefinitionReader#loadBeanDefinitions()
办法来调用 ImportBeanDefinitionRegistrar#registerBeanDefinitions()
办法。
ImportBeanDefinitionRegistrar#registerBeanDefinitions()
办法就是 ImportBeanDefinitionRegistrar
的实现类要实现的办法。
public void loadBeanDefinitions(Set<ConfigurationClass> configurationModel) {TrackedConditionEvaluator trackedConditionEvaluator = new TrackedConditionEvaluator();
for (ConfigurationClass configClass : configurationModel) {loadBeanDefinitionsForConfigurationClass(configClass, trackedConditionEvaluator);
}
}
private void loadBeanDefinitionsForConfigurationClass(ConfigurationClass configClass, TrackedConditionEvaluator trackedConditionEvaluator) {
// 疏忽下面的代码
// 这里就是调用 ImportBeanDefinitionRegistrars#registerBeanDefinitions() 办法的入口
loadBeanDefinitionsFromRegistrars(configClass.getImportBeanDefinitionRegistrars());
}
private void loadBeanDefinitionsFromRegistrars(Map<ImportBeanDefinitionRegistrar, AnnotationMetadata> registrars) {registrars.forEach((registrar, metadata) ->
// 调用 ImportBeanDefinitionRegistrars#registerBeanDefinitions() 办法
registrar.registerBeanDefinitions(metadata, this.registry, this.importBeanNameGenerator));
}