Back to Javatutorial

ConfigurationClassPostProcessor(三):处理@Import注解

docs/Spring全家桶/Spring源码分析/Spring重要机制探秘/ConfigurationClassPostProcessor(三):处理@Import注解.md

1.0.026.1 KB
Original Source

ConfigurationClassPostProcessor ĵƪҪǷ spring @Import עĴ̡

4. spring δ @Import עģ

нģǼ spring @Import עĴ̡

4.1 ˽ @Import ע

@Import עĶ壺

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Import {
    /**
     * {@link Configuration @Configuration}, {@link ImportSelector},
     * {@link ImportBeanDefinitionRegistrar}, or regular component classes to import.
     */
    Class<?>[] value();
}

@Import һvalue()ֵ֧ Classĵ֧ 4 ֣

  • @Configuration עǵ
  • ʵ ImportSelector
  • ʵ ImportBeanDefinitionRegistrar
  • ͨ

ͨһ demo չʾʹ @Import νർ뵽 spring С

4.2 demo ׼

  1. ׼ 4 bean
/**
 * Element01
 */
public class Element01 {
    public String desc() {
        return "this is element 01";
    }
}

/**
 * Element02
 */
public class Element02 {
    public String desc() {
        return "this is element 02";
    }
}

/**
 * Element03
 */
public class Element03 {
    public String desc() {
        return "this is element 03";
    }
}

/**
 * Element04
 */
public class Element04 {
    public String desc() {
        return "this is element 04";
    }
}
  1. ׼ʵ ImportBeanDefinitionRegistrarelement02 ע
public class Element02ImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {

    /**
     *  registerBeanDefinitions עelement02ӦBeanDefinition
     * Ҳǰ Element02 Ӧ beanDefinition ֶעᵽbeanFactory 
     *  beanDefinitionMap 
     */
    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, 
            BeanDefinitionRegistry registry) {
        registry.registerBeanDefinition("element02", new RootBeanDefinition(Element02.class));
    }
}
  1. ׼ʵ ImportSelectorselectImports(...) У Element03 ""
public class Element03Selector implements ImportSelector {
    /**
     * String Ϊ .
     * ںҪõ䣬˱"."
     * @param importingClassMetadata
     * @return
     */
    @Override
    public String[] selectImports(AnnotationMetadata importingClassMetadata) {
        return new String[] {Element03.class.getName()};
    }
}
  1. ׼һ @Configuration ע࣬ͨб @Bean ǵķ Element04
@Configuration
public class Element04Configuration {
    @Bean
    public Element04 element04() {
        return new Element04();
    }

}
  1. @EnableElement ע⣬е @Import ע Element01.class``Element02ImportBeanDefinitionRegistrar.class``Element03Selector.class``Element04Configuration.class
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import({
        // ͨ 
        Element01.class,
        // ʵ ImportBeanDefinitionRegistrar 
        Element02ImportBeanDefinitionRegistrar.class,
        // ʵ ImportSelector 
        Element03Selector.class,
        //  @Configuration ǵ
        Element04Configuration.class
})
public @interface EnableElement {

}
// ֻҪ @EnableElement ע
@EnableElement
public class Demo04Main {

    public static void main(String[] args) {
        //  Demo04Main.class
        ApplicationContext context = new AnnotationConfigApplicationContext(Demo04Main.class);

        Element01 element01 = context.getBean(Element01.class);
        System.out.println(element01.desc());

        Element02 element02 = context.getBean(Element02.class);
        System.out.println(element02.desc());

        Element03 element03 = context.getBean(Element03.class);
        System.out.println(element03.desc());

        Element04 element04 = context.getBean(Element04.class);
        System.out.println(element04.desc());
    }
}

gitee/funcy.

У£

this is element 01
this is element 02
this is element 03
this is element 04

Կ4 bean ɹ spring ͨ spring δġ

ע ConfigurationClassPostProcessor ĵƪǰƪ£ @ComponentScan ע @Bean עͬĴ룬Ļһʴˡ

4.3 ࣺConfigurationClassPostProcessor#processConfigBeanDefinitions

Ḷ̌ǰƪѾᵽˣֱӿؼ룺

public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
    ...
    Set<BeanDefinitionHolder> candidates = new LinkedHashSet<>(configCandidates);
    Set<ConfigurationClass> alreadyParsed = new HashSet<>(configCandidates.size());
    do {
        // 1. , @Component@PropertySources@ComponentScans
        // @ImportResourceȵĽ
        parser.parse(candidates);
        parser.validate();
        // ɺ󣬵õ࣬ౣ parser  configurationClasses 
        Set<ConfigurationClass> configClasses 
                = new LinkedHashSet<>(parser.getConfigurationClasses());
        ...

        // 2.  @Import ࡢд@Beanķ
        // @ImportResource ԴתBeanDefinition
        this.reader.loadBeanDefinitions(configClasses);
        ...
        // עBeanDefinition  candidateNamesбȽ
        // ڵĻ˵µBeanDefinitionע
        if (registry.getBeanDefinitionCount() > candidateNames.length) {
            ...
            for (String candidateName : newCandidateNames) {
                // ˱BeanDefinition
                if (!oldCandidateNames.contains(candidateName)) {
                    BeanDefinition bd = registry.getBeanDefinition(candidateName);
                    // 3. ӵ࣬࣬δӵcandidatesУȴ´ѭ
                    if (ConfigurationClassUtils.checkConfigurationClassCandidate(
                            bd, this.metadataReaderFactory) 
                            &&!alreadyParsedClasses.contains(bd.getBeanClassName())) {
                        candidates.add(new BeanDefinitionHolder(bd, candidateName));
                    }
                }
            }
            candidateNames = newCandidateNames;
        }
    }
    while (!candidates.isEmpty());
    ...
}

ϴ뾭һЩֻ˴ @Import ؼ裬ܽ£

  1. @Component``@PropertySources``@ComponentScans``@ImportResource ȵĽ ǰƪҲˣǾۼ @Import ٴηһҪֻһ main() ע Demo04.class

  2. @Import ࡢд @Bean ķ@ImportResource Դת BeanDefinitionǰ @Bean ʱҲˣҲ

  3. ӵ࣬࣬δӵ candidates Уȴ´ѭ

4.4 ࣺConfigurationClassParser#doProcessConfigurationClass

@Import νģ ConfigurationClassParser#doProcessConfigurationClass

/**
 * ķ
 */
protected final SourceClass doProcessConfigurationClass(ConfigurationClass configClass, 
        SourceClass sourceClass) throws IOException {
    // 1.  @Component ע⣬ݹ鴦ڲ࣬IJע
    ...

    // 2. @PropertySourceע⣬IJע
    ...

    // 3.  @ComponentScan/@ComponentScans ע⣬IJע
    ...

    // 4. @Importע
    processImports(configClass, sourceClass, getImports(sourceClass), true);

    // 5. @ImportResourceע⣬IJע
    ...

    // 6. @Beanע⣬IJע
    ...

    // 7. ĸ࣬ processConfigurationClass(...) һѭʱ
    ...
    return null;
}

@Import עõ processImports(...) Ǽ

1. ȡ @Import

ǰĿŵ processImports(...)

processImports(configClass, sourceClass, getImports(sourceClass), true);

4

  • configClassdemo04Main Ӧࣻ
  • sourceClass demo04Main ϵעİװ
  • getImports(sourceClass)``getImports(...) ȡ sourceClass @Import עࣻ
  • trueֵǷѭ롣

Уȡ @Import ע getImports(...) Ĺܣλȡģ

private Set<SourceClass> getImports(SourceClass sourceClass) throws IOException {
    Set<SourceClass> imports = new LinkedHashSet<>();
    Set<SourceClass> visited = new LinkedHashSet<>();
    // ȡ
    collectImports(sourceClass, imports, visited);
    return imports;
}

/**
 * Ļȡ
 */
private void collectImports(SourceClass sourceClass, Set<SourceClass> imports, 
        Set<SourceClass> visited) throws IOException {
    if (visited.add(sourceClass)) {
        for (SourceClass annotation : sourceClass.getAnnotations()) {
            String annName = annotation.getMetadata().getClassName();
            if (!annName.equals(Import.class.getName())) {
                // annotationƲimportݹ collectImports(...) 
                collectImports(annotation, imports, visited);
            }
        }
        // ȡǰ @Import ע
        imports.addAll(sourceClass.getAnnotationAttributes(Import.class.getName(), "value"));
    }
}

ȡ @Import ķ ConfigurationClassParser#collectImportsȡȡʽ£

  1. ȡע⣻
  2. Щע⣬ @Import ע⣬ȡ @Import value ֵ򣬻صһ

֮ demo04Main ϵ @EnableElement עᱻȡעⲻ @Import ע⣬ͼȡ @EnableElement ϵע⣬ʱ @EnableElement @Import ע⣬ʱͻȡ @Import value() ֵҲ @Import עࡣ

к õĽ£

õĽΪ LinkedHashSetһνͼ㣬˷Ϊ 4 ͼԿ@Import ע 4 ඼ȡˣ

2. @Import

ȡ @Import ע⵼ processImports(...)

private void processImports(ConfigurationClass configClass, SourceClass currentSourceClass,
        Collection<SourceClass> importCandidates, boolean checkForCircularImports) {
    ...
    for (SourceClass candidate : importCandidates) {
        // 1.  ImportSelector
        if (candidate.isAssignable(ImportSelector.class)) {
            Class<?> candidateClass = candidate.loadClass();
            // ʵ ImportSelectorһִ Aware ӿڷ
            // ֵ֧AwareBeanClassLoaderAwareBeanFactoryAwareEnvironmentAwareResourceLoaderAware
            ImportSelector selector = ParserStrategyUtils.instantiateClass(candidateClass, 
                    ImportSelector.class, this.environment, this.resourceLoader, this.registry);
            if (selector instanceof DeferredImportSelector) {
                this.deferredImportSelectorHandler.handle(configClass, (DeferredImportSelector) selector);
            }
            else {
                // ִ selectImports ȡ࣬Ϊ"."
                String[] importClassNames = selector.selectImports(currentSourceClass.getMetadata());
                Collection<SourceClass> importSourceClasses = asSourceClasses(importClassNames);
                // ݹ processImports(...) һδ
                processImports(configClass, currentSourceClass, importSourceClasses, false);
            }
        }
        // 2.  ImportBeanDefinitionRegistrar
        else if (candidate.isAssignable(ImportBeanDefinitionRegistrar.class)) {
            Class<?> candidateClass = candidate.loadClass();
            // ʵ ImportBeanDefinitionRegistrarִ Aware ӿڵķ
            // ֵ֧AwareBeanClassLoaderAwareBeanFactoryAwareEnvironmentAwareResourceLoaderAware
            ImportBeanDefinitionRegistrar registrar = ParserStrategyUtils
                    .instantiateClass(candidateClass, ImportBeanDefinitionRegistrar.class, 
                    this.environment, this.resourceLoader, this.registry);
            //  ImportBeanDefinitionRegistrar 
            configClass.addImportBeanDefinitionRegistrar(registrar, currentSourceClass.getMetadata());
        }
        // 3. ߣ processConfigurationClass(...) ֱӽ
        // ࣨ @Component@Configuration@Import ע⣩н
        else {
            this.importStack.registerImport(
                    currentSourceClass.getMetadata(), candidate.getMetadata().getClassName());
            processConfigurationClass(candidate.asConfigClass(configClass));
        }
    }

    ...
}

ǾĴ룬ֻ @Import Ĺؼ裺

  1. ImportSelector£

    1. ʹ÷ʵ ImportSelectorִ֮ Aware ӿڷڴ ImportSelector ʱʵ Aware ӿڣֵ֧ Aware BeanClassLoaderAware``BeanFactoryAware``EnvironmentAware``ResourceLoaderAware
    2. ִ ImportSelector ʵ selectImports һΪ˻ȡ࣬Ϊ Class[] ""Element03Selector и÷£
@Override
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
    return new String[] {Element03.class.getName()};
}

һȡ Element03.class; 3. ȡ Class 飬ת SourceClass ϣһε processImports(...)ڵڶεʱ Element03

  1. ImportBeanDefinitionRegistrar£

    1. ʵ ImportBeanDefinitionRegistrarִ Aware ӿڵķһͬ ImportSelector ʵһ׸
    2. һõ ImportBeanDefinitionRegistrar ʵ浽 configClass Уٷʵδģ
  2. Ͳߣ processConfigurationClass(...) ֱӽǰƪѾἰˣ @Component``@Import``@ComponentScan``@Configuration``@Bean עģһΪ˽еЩע⣬ Element01``Element02``Element03( 1 ᵽģ Element03Selector лȡ Element03.class 󣬽ת SourceClassٴε processImports(...) Ĺ) һġ

Ƿ֣ ImportBeanDefinitionRegistrar ķʽ⣬뷽ʽͨࡢࡢImportSelector ʵࣩһĴʽǰĽʽյõ processConfigurationClass(...) һ ǰƪѾηˣͲٷˣ ImportBeanDefinitionRegistrar Ĵ

4.5 BeanDefinitions``ConfigurationClassBeanDefinitionReader#loadBeanDefinitions

ڷ @Bean ʱǷ ConfigurationClassBeanDefinitionReader#loadBeanDefinitions @Bean ̣ @Import ֱ̣ӽؼ ConfigurationClassBeanDefinitionReader#loadBeanDefinitionsForConfigurationClass

private void loadBeanDefinitionsForConfigurationClass(
        ConfigurationClass configClass, TrackedConditionEvaluator trackedConditionEvaluator) {
    ...

    //  @Import 
    if (configClass.isImported()) {
        registerBeanDefinitionForImportedConfigurationClass(configClass);
    }
    //  @Bean 
    for (BeanMethod beanMethod : configClass.getBeanMethods()) {
        loadBeanDefinitionsForBeanMethod(beanMethod);
    }
    //  @ImportResource Դ
    loadBeanDefinitionsFromImportedResources(configClass.getImportedResources());
    //  @Import  ImportBeanDefinitionRegistrar
    // ǰ汣configClassеImportBeanDefinitionRegistrarsʹ
    loadBeanDefinitionsFromRegistrars(configClass.getImportBeanDefinitionRegistrars());
}

@Import ĵط

  1. @Import
  2. @Import ImportBeanDefinitionRegistrar

Ƿֱδġ

1. @Import

@Import شΪ

    //  @Import 
    if (configClass.isImported()) {
        registerBeanDefinitionForImportedConfigurationClass(configClass);
    }

ǽһ̽

private void registerBeanDefinitionForImportedConfigurationClass(ConfigurationClass configClass) {
    AnnotationMetadata metadata = configClass.getMetadata();
    //  BeanDefinitionΪ AnnotatedGenericBeanDefinition
    AnnotatedGenericBeanDefinition configBeanDef = new AnnotatedGenericBeanDefinition(metadata);
    // һϵе
    ScopeMetadata scopeMetadata = scopeMetadataResolver.resolveScopeMetadata(configBeanDef);
    configBeanDef.setScope(scopeMetadata.getScopeName());
    String configBeanName = this.importBeanNameGenerator.generateBeanName(configBeanDef, this.registry);
    AnnotationConfigUtils.processCommonDefinitionAnnotations(configBeanDef, metadata);
    BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(configBeanDef, configBeanName);
    definitionHolder = AnnotationConfigUtils
            .applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
    // ע
    this.registry.registerBeanDefinition(definitionHolder.getBeanName(), 
            definitionHolder.getBeanDefinition());
    configClass.setBeanName(configBeanName);
}

һעᵽ BeanDefinition еḶ́ʹõ BeanDefinition AnnotatedGenericBeanDefinition

2. @Import ImportBeanDefinitionRegistrar

ù̵ķΪ loadBeanDefinitionsFromRegistrars(...)£

private void loadBeanDefinitionsFromRegistrars(Map<ImportBeanDefinitionRegistrar, 
        AnnotationMetadata> registrars) {
    registrars.forEach((registrar, metadata) ->
            registrar.registerBeanDefinitions(metadata, this.registry, 
                    this.importBeanNameGenerator));
}

÷DZ ImportBeanDefinitionRegistrar ϣȻһе ImportBeanDefinitionRegistrar#registerBeanDefinitions(AnnotationMetadata, BeanDefinitionRegistry, BeanNameGenerator) ÷λ ImportBeanDefinitionRegistrar ӿڣ£

public interface ImportBeanDefinitionRegistrar {

    /**
     * ĬϷĬʵֽһ
     */
    default void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, 
            BeanDefinitionRegistry registry,BeanNameGenerator importBeanNameGenerator) {
        registerBeanDefinitions(importingClassMetadata, registry);
    }

    /**
     *  Element02ImportBeanDefinitionRegistrar ʵֵķ
     */
    default void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, 
            BeanDefinitionRegistry registry) {
    }

}

ImportBeanDefinitionRegistrar#registerBeanDefinitions(AnnotationMetadata, BeanDefinitionRegistry, BeanNameGenerator) һãյõ ImportBeanDefinitionRegistrar#registerBeanDefinitions(AnnotationMetadata, BeanDefinitionRegistry)ǵ Element02ImportBeanDefinitionRegistrar ʵ˸÷

public class Element02ImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, 
            BeanDefinitionRegistry registry) {
        registry.registerBeanDefinition("element02", new RootBeanDefinition(Element02.class));
    }
}

˴죬շ ImportBeanDefinitionRegistrar עᵽ beanDefinitionMap ߼Լдģ

3. лȡ ElementXx

Element01``Element02``Element03``Element04 ͵עᵽ beanDefinitionMap ˣǿһ beanDefinitionNames еݣ

Է֣Element01 Element03 beanName ͬѰ bean 뷽ʽΪ

ʹ beanFactory.get(beanName) ʱҪע⣺

// ȡᱨ
beanFactory.get("element01");
// ܻȡ
beanFactory.get("element02");
// ȡᱨ
beanFactory.get("element03");
// ܻȡ
beanFactory.get("element04");

ʹ beanFactory.get(beanName) ȡ element01 element03 Ҫȡ

// ܻȡ
beanFactory.get("org.springframework.learn.explore.demo04.element.Element01");
// ܻȡ
beanFactory.get("org.springframework.learn.explore.demo04.element.Element03");

ȻҲʹ beanFactory.get(Class) ķʽȡ

// ܻȡ
beanFactory.get(Element01.class);
// ܻȡ
beanFactory.get(Element02.class);
// ܻȡ
beanFactory.get(Element03.class);
// ܻȡ
beanFactory.get(Element04.class);

4.6 䣺DeferredImportSelector Ĵ

ڷ ConfigurationClassParser#processImports ʱ ImportSelector ʱôһδ룺

δж selector ǷΪ DeferredImportSelector ʵǾͰ DeferredImportSelector ͵ʵдͰͨ ImportSelector DeferredImportSelector ͨ ImportSelector кβͬ

DeferredImportSelector Ĵ£

/**
 * DeferredImportSelector  ImportSelectorӽӿ
 */
public interface DeferredImportSelector extends ImportSelector {

    /**
     * ص
     */
    @Nullable
    default Class<? extends Group> getImportGroup() {
        return null;
    }


    /**
     * Ķ
     */
    interface Group {

        /**
         * ÷Ĵ
         */
        void process(AnnotationMetadata metadata, DeferredImportSelector selector);

        /**
         * ظ÷
         */
        Iterable<Entry> selectImports();


        /**
         * Ԫض
         */
        class Entry {

            /**
             * ע
             */
            private final AnnotationMetadata metadata;

            /**
             * 
             */
            private final String importClassName;

            public Entry(AnnotationMetadata metadata, String importClassName) {
                this.metadata = metadata;
                this.importClassName = importClassName;
            }

            // ʡ get/set ʡ equals/toString/hashCode 
            ...

        }
    }
}

ĴԿ

  • DeferredImportSelector ImportSelector ӽӿڣ߱ ImportSelector Ĺ
  • DeferredImportSelector ṩһClass<? extends Group> getImportGroup()÷صǵǰ DeferredImportSelector ʵڵķ顣

עд룺

this.deferredImportSelectorHandler.handle(configClass, (DeferredImportSelector) selector);

дʲô ConfigurationClassParser#handler

class ConfigurationClassParser {

    ...

    private class DeferredImportSelectorHandler {

        @Nullable
        private List<DeferredImportSelectorHolder> deferredImportSelectors = new ArrayList<>();

        public void handle(ConfigurationClass configClass, DeferredImportSelector importSelector) {
            //  configClass  importSelector װ DeferredImportSelectorHolder
            DeferredImportSelectorHolder holder = new DeferredImportSelectorHolder(
                    configClass, importSelector);
            if (this.deferredImportSelectors == null) {
                DeferredImportSelectorGroupingHandler handler 
                    = new DeferredImportSelectorGroupingHandler();
                handler.register(holder);
                handler.processGroupImports();
            }
            else {
                // ӵ deferredImportSelectors 
                this.deferredImportSelectors.add(holder);
            }
        }
        ...
    }
    ...
}

ԿϴȽ configClass importSelector װ DeferredImportSelectorȻӵ deferredImportSelectors

ĿǰΪֹDeferredImportSelector ಢûндô DeferredImportSelector ﴦأǻص ConfigurationClassParser#parse(Set<BeanDefinitionHolder>)

public class  ConfigurationClassParser {
    public void parse(Set<BeanDefinitionHolder> configCandidates) {
        // ѭ
        for (BeanDefinitionHolder holder : configCandidates) {
            BeanDefinition bd = holder.getBeanDefinition();
            try {
                // BeanDefinitionAnnotatedBeanDefinitionʵ
                if (bd instanceof AnnotatedBeanDefinition) {
                    parse(((AnnotatedBeanDefinition) bd).getMetadata(), holder.getBeanName());
                }
                ...
            }
            catch (BeanDefinitionStoreException ex) {
                throw ex;
            }
            catch (Throwable ex) {
                ...
            }
        }
        // ﴦ DeferredImportSelector
        this.deferredImportSelectorHandler.process();
    }
    ...
}

ԿڴĽ DeferredImportSelectorҲӵ deferredImportSelectors ݣõ deferredImportSelectorHandler.process().

Ǽ

class ConfigurationClassParser {

    private class DeferredImportSelectorHandler {
        ...
        public void process() {
            List<DeferredImportSelectorHolder> deferredImports = this.deferredImportSelectors;
            this.deferredImportSelectors = null;
            try {
                if (deferredImports != null) {
                    DeferredImportSelectorGroupingHandler handler 
                        = new DeferredImportSelectorGroupingHandler();
                    // DeferredImportSelector ָ˳@Order/Orderd
                    deferredImports.sort(DEFERRED_IMPORT_COMPARATOR);
                    //  DeferredImportSelectorGroupingHandler#register 
                    deferredImports.forEach(handler::register);
                    // 
                    handler.processGroupImports();
                }
            }
            finally {
                this.deferredImportSelectors = new ArrayList<>();
            }
        }
        ...
    }
    ...
}

process() £

  1. ҪǸ @Order ע⣬ʵ Orderd ӿ
  2. DeferredImportSelectorGroupingHandler#register ʵǽ deferredImports еԪעᵽ handler У
  3. handler.processGroupImports()

handler.processGroupImports()

class ConfigurationClassParser {

    ...

    private class DeferredImportSelectorGroupingHandler {
        ...
        /**
         * յĴ
         * ﴦ鵼
         */
        public void processGroupImports() {
            for (DeferredImportSelectorGrouping grouping : this.groupings.values()) {
                // 飬 grouping.getImports()ǹؼ
                grouping.getImports().forEach(entry -> {
                    ConfigurationClass configurationClass = this.configurationClasses.get(
                            entry.getMetadata());
                    try {
                        // ͬImportSelectorʵһҲǵ processImports(...) 
                        // ע entry.getImportClassName()һε processImports(...) IJ
                        // ImportSelector
                        processImports(configurationClass, asSourceClass(configurationClass),
                                asSourceClasses(entry.getImportClassName()), false);
                    }
                    catch (...) {
                        ...
                    }
                });
            }
        }
        ...
    }
    ...

}

processGroupImports(...) Ҫ߼£

  1. grouping.getImports() ȡ
  2. processImports ĵ룬ͬ ImportSelector ӿһ

grouping.getImports() ÷Ϊ ConfigurationClassParser.DeferredImportSelectorGrouping#getImports£

public Iterable<Group.Entry> getImports() {
    for (DeferredImportSelectorHolder deferredImport : this.deferredImports) {
        // ִ Group#process
        this.group.process(deferredImport.getConfigurationClass().getMetadata(),
                deferredImport.getImportSelector());
    }
    // ִ Group#selectImports
    return this.group.selectImports();
}

DeferredImportSelector.Group

  • DeferredImportSelector.Group#process
  • DeferredImportSelector.Group#selectImports

Сڵһʼ뼰עͣ DeferredImportSelector.Group#selectImports ص.

ϰ죬ܽ DeferredImportSelector ImportSelector ߵ

  • DeferredImportSelector ָ飺ڴʱԸݷͳһ
  • DeferredImportSelector ʱ֮ٴ
  • DeferredImportSelector ķأͬ ImportSelector ImportSelector#selectImports أ DeferredImportSelector.Group#selectImports ء

4.7 ܽ

Ҫ ConfigurationClassPostProcessor @Import עĴܽ:

  1. @Import ɵ 4 ֱ֣ͨࡢࡢʵ ImportSelector Լʵ ImportBeanDefinitionRegistrar
  2. ȡ @Import ע⣺spring ڻȡϵ @Import ʱȻȡϵע⣬Ȼһжϣǰע @Importȡ @ImportImport#value)ȡǰעϵע⣬ظϴ
  3. @Import ࣺͨࡢͳһʵ ImportSelectorselectImports(...) ص õ classȻҲǰʵ ImportBeanDefinitionRegistrar ࣬ѶӦʵ浽ǰУעᵽ beanDefinitionMap ʱǴȡģ
  4. עᵽ beanDefinitionMapʵ ImportSelector յõһͨ࣬ͬͨһֱע᣻ʵ ImportBeanDefinitionRegistrarImportBeanDefinitionRegistrar#registerBeanDefinitions(AnnotationMetadata, BeanDefinitionRegistry) עᣬע߼ʵж塣

ԭӣhttps://my.oschina.net/funcy/blog/4678152 ߸ˮƽд֮ӭָԭףҵתϵ߻Ȩҵתע