@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 的办法:

  1. BeanClassLoaderAware
  2. BeanFactoryAware
  3. EnvironmentAware
  4. 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 子类,也会依照以下程序来执行:

  1. BeanClassLoaderAware
  2. BeanFactoryAware
  3. EnvironmentAware
  4. 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 办法。他次要做了这些事件:

  1. processConfigBeanDefinitions 先去扫描 BeanDefinitionRegistry 保护的 BeanDefinitionNames 列表
  2. 通过 BeanDefinitionNames 列表转换成 configCandidates 列表
  3. configCandidates 列表的元素做排序操作
  4. 通过 ConfigurationClassParser#parse() 办法,去读取 configCandidates 列表,并将 configCandidates 列表中有应用到的 @Import 注解的类,调用它们相干的办法。
    例如 ImportSelector#selectImports() 办法
    并且将调用办法后失去的后果,存入到 ConfigurationClassParser.configurationClasses 的 map 中去
  5. 调用 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));}