@Import 是一个能让类生成为 Spring Bean 的注解。
@Import 注解它次要是配合 ImportSelector 和 @ImportBeanDefinitionRegistrar 的子类,或者一般的 Java Bean 类应用。
@Import 注解源码
@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)@Documentedpublic @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 setbeanFactory setenvironment setresourceLoader setinvoke selectImports methodtest bean
配合自定义注解应用
ImportSelector 还能配合自定义注解,来决定须要引入的 Bean。
例子
/** * 这里同时引入 TestBeanClassAnnotation 和 AnotherTestBeanClassAnnotation 这2个注解 * 那么会将 TestBeanClass 和 AnotherTestBeanClass 对应的 Bean 加到到 Spring 容器中去 * 能够只应用其中一个注解,以只加载注解关联的 Bean */@SpringBootTest@ImportSelectorTest.TestBeanClassAnnotation@ImportSelectorTest.AnotherTestBeanClassAnnotationpublic 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 setbeanFactory setenvironment setresourceLoader setinvoke selectImports methodtest beananother 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));}