Import 注解與 ImportSelector 和 ImportBeanDefinitionRegistrar

@Import注解常出現(xiàn)在@Enable注解里面,上一篇@Enable 注解原理解析里知道@Enable只所以能發(fā)生作用,對Spring進(jìn)行配置主要靠的就是@Import注解

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Import {

    /**
     * {@link Configuration}, {@link ImportSelector}, {@link ImportBeanDefinitionRegistrar}
     * or regular component classes to import.
     */
    Class<?>[] value();

}

它的源碼很簡單,value為一個(gè)Class的數(shù)組,只要這些Class是加上@Configuration注解,或者實(shí)現(xiàn)了ImportSelectorImportBeanDefinitionRegistrar就會自動加載了

我們簡單介紹一下這三種情況

@Configuration注解我就不說了

ImportBeanDefinitionRegistrar

public interface ImportBeanDefinitionRegistrar {
    public void registerBeanDefinitions(
            AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry);
}

AnnotationMetadata就是你加上@Import注解的地方
BeanDefinitionRegistry然后你就可以把你需要的BeanDefinition注冊進(jìn)去

ImportSelector

public interface ImportSelector {
    String[] selectImports(AnnotationMetadata importingClassMetadata);
}

ImportSelector返回一個(gè)Class的數(shù)組,這些類也可以實(shí)現(xiàn)ImportBeanDefinitionRegistrarImportSelector再進(jìn)行配置,有點(diǎn)遞歸的趕腳,后面看他的源碼實(shí)現(xiàn)就是遞歸

上面三種情況可以同時(shí)滿足嗎

答案是否定的

我們看一下ConfigurationClassParser#processImports

for (SourceClass candidate : importCandidates) {
    // 如果import的類實(shí)現(xiàn)了ImportSelector
    if (candidate.isAssignable(ImportSelector.class)) {
        // Candidate class is an ImportSelector -> delegate to it to determine imports
        Class<?> candidateClass = candidate.loadClass();
        ImportSelector selector = BeanUtils.instantiateClass(candidateClass, ImportSelector.class);
        ParserStrategyUtils.invokeAwareMethods(
                selector, this.environment, this.resourceLoader, this.registry);
        if (this.deferredImportSelectors != null && selector instanceof DeferredImportSelector) {
            this.deferredImportSelectors.add(
                    new DeferredImportSelectorHolder(configClass, (DeferredImportSelector) selector));
        }
        else {
            String[] importClassNames = selector.selectImports(currentSourceClass.getMetadata());
            Collection<SourceClass> importSourceClasses = asSourceClasses(importClassNames);
            // 遞歸調(diào)用processImports
            processImports(configClass, currentSourceClass, importSourceClasses, false);
        }
    }
    // 如果import的類實(shí)現(xiàn)了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 =
                BeanUtils.instantiateClass(candidateClass, ImportBeanDefinitionRegistrar.class);
        ParserStrategyUtils.invokeAwareMethods(
                registrar, this.environment, this.resourceLoader, this.registry);
        configClass.addImportBeanDefinitionRegistrar(registrar, currentSourceClass.getMetadata());
    }
    // 都不滿足,當(dāng)做@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));
    }
}

ImportBeanDefinitionRegistrar的調(diào)用細(xì)節(jié)我們后面再說.

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容