以下都是基于spring-5.2.8,之前的版本可能有所不同
import 是spring中的一个注解,可以用来导入需要实例化的类,把这些类加入spring容器
而且通过import导入进来的类是可以获取到父类上面的注解的信息,当然父类必须要先加入spring管理这个注解能起作用,这个注解是作用于类,接口上面的。
@Component
@import({DeferredimportSelectorDemo.class,SelectimportDemo.class,AwareBean.class})
public class importBean {
}
Improt注解使用也是很简单的,只需要在注解里面加上需要实例化的类就行了,当然import进来的类也可以实现一些接口。
importSelector,importBeanDefinitionRegistrar两个接口是比较特殊的接口,实现这两个接口的类必须是通过import导入的,这两个接口的方法才会被调用。
selectimports 方法 入参是导入类的信息,返回值是String数组,数组里面是需要实例化的类的完整限定名 Dome.class.getName()
public class SelectimportDome implements importSelector {
@Override
public String[] selectimports(Annotationmetadata importingClassmetadata) {
MergedAnnotations annotations = importingClassmetadata.getAnnotations();
MergedAnnotation eas = annotations.get(EnableAspectJAutoProxy.class);
Object proxyTargetClass = eas.getValue("proxyTargetClass").get();
//类的完整限定名,
return new String[]{Dome.class.getName()};
}
}
@Improt注解是由 ConfigurationClassPostProcessor 处理的 ,这个类实现了 BeanDefinitionRegistryPostProcessor 在spring容器初始的时候会 调用 postProcessBeanDefinitionRegistry ,postProcessBeanFactory这个两个方法
postProcessBeanDefinitionRegistry方法会收集注解,包装注册beanDefinition
这个是具体处理@import注解的方法
具体方法代码
private void processimports(ConfigurationClass configClass, SourceClass currentSourceClass, CollectionimportCandidates, Predicate exclusionFilter, boolean checkForCircularimports) { //如果没有@import注解直接返回,不处理 if (importCandidates.isEmpty()) { return; } if (checkForCircularimports && isChainedimportonStack(configClass)) { this.problemReporter.error(new CircularimportProblem(configClass, this.importStack)); } else { this.importStack.push(configClass); try { //循环类上面的每一个@import for (SourceClass candidate : importCandidates) { //如果import进来的是一个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 selectorFilter = selector.getExclusionFilter(); if (selectorFilter != null) { exclusionFilter = exclusionFilter.or(selectorFilter); } //如果是一个DeferredimportSelector类型 if (selector instanceof DeferredimportSelector) { //比较复杂,springboot中自动配置用到了 this.deferredimportSelectorHandler.handle(configClass, (DeferredimportSelector) selector); } else { //在这里调用selectimports方法,返回所有的需要import到spring容器的beanName String[] importClassNames = selector.selectimports(currentSourceClass.getmetadata()); Collection importSourceClasses = asSourceClasses(importClassNames, exclusionFilter); //递归处理,有可能import进来的类又有@import注解 processimports(configClass, currentSourceClass, importSourceClasses, exclusionFilter, false); } } //如果import进来的是一个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); //加入到importBeanDefinitionRegistrars容器中,这里还没有调用registerBeanDefinitions configClass.addimportBeanDefinitionRegistrar(registrar, currentSourceClass.getmetadata()); } 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); } finally { this.importStack.pop(); } } }
1. import 引入没有实现importSelector,importBeanDefinitionRegistrar接口的类会直接解析这个类
2. 1).如果是实现了importSelector 接口的类 就会反射实例化,然后调用selectimports方法
2).如果是实现了DeferredimportSelector 接口,会调到 DeferredimportSelectorGrouping里面的selectimports方法
其实获取方式还是importSelector 的selectimports
DeferredimportSelectorGrouping 也可以是自己实现的
如果没有自己实现就是走默认的
3. 实现了importBeanDefinitionRegistrar 接口的,会先加入importBeanDefinitionRegistrars map里面,然后处理



