@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)了ImportSelector或ImportBeanDefinitionRegistrar就會自動加載了
我們簡單介紹一下這三種情況
@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)ImportBeanDefinitionRegistrar或ImportSelector再進(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é)我們后面再說.