@Import可以导入以下几种种类:
-
普通类
-
实现ImportSelector接口的类
-
实现DeferredImportSelector接口的类
-
实现ImportBeanDefinitionRegistrar接口的类
普通类
被导入的类会被容器注册成一个Bean,可以被依赖注入使用。【4.2 版本之前只可以导入配置类;4.2版本之后也可以导入普通类,导入的类会被当作配置类】
@Import注册一个类时,这个配置类不应该被@Component或者@Configuration注解标记。Spring中会将所有的bean class封装成一个ConfigurationClass,并且此后会判断被封装的bean class是否是由其他类导入的.
@Configuration @Import(OtherBean.class) public class SpringConfig { }
public class OtherBean { }
ImportSelector实现类
实现类不会被注册成Bean,接口方法的返回值会被注册成Bean。【BeanName是全类名】
@Configuration @Import(MyImportSelector.class) public class SpringConfig { }
public class MyImportSelector implements ImportSelector { @Override public String[] selectImports(AnnotationMetadata importingClassMetadata) { return new String[]{OtherBean.class.getName()}; } }
DeferredImportSelector实现类
DeferredImportSelector是ImportSelector的子接口, 所以它们的实现方式一样,只是Spring的处理方式不同。DeferredImportSelector和SpringBoot中自动导入配置文件的延迟导入有关。
@Configuration @Import(MyDeferredImportSelector.class) public class SpringConfig { }
public class MyDeferredImportSelector implements DeferredImportSelector { @Override public String[] selectImports(AnnotationMetadata importingClassMetadata) { return new String[]{OtherBean.class.getName()}; } }
ImportBeanDefinitionRegistrar实现类
实现类不会被注册为bean,但是会回调其接口方法,由开发者通过Spring api手动向Spring容器注册bean。【类似于BeanFactoryPostRegister】
@Configuration @Import(MyImportBeanDefinitionRegistrar.class) public class SpringConfig { }
public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar { @Override public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) { BeanDefinition beanDefinition = new RootBeanDefinition(); String beanName = StringUtils.uncapitalize(OtherBean.class.getSimpleName()); beanDefinition.setBeanClassName(OtherBean.class.getName()); registry.registerBeanDefinition(beanName,beanDefinition); } }