@import 配合 importselector 可在 spring 启动时动态导入配置类,通过重写 selectimports 方法返回全限定类名数组,支持基于环境、类存在性或注解属性条件化加载;其执行早于 beanfactory 初始化,仅可注入 environment 等基础设施 bean。

@Import 注解配合 ImportSelector 是 Spring 提供的高级扩展机制,用于在运行时动态决定要导入哪些配置类,而不是写死在注解里。它的核心在于让 Spring 容器启动时调用你自定义的 selectImports 方法,由你返回一组全限定类名(String[]),Spring 就会把对应类作为配置类加载进去。
ImportSelector 的基本用法
实现 ImportSelector 接口,重写 selectImports(AnnotationMetadata importingClassMetadata) 方法:
- importingClassMetadata:当前标注 @Import 的类的注解元数据,可用来读取该类上其他注解(比如自定义启用注解)
- 方法必须返回非 null 的
String[],每个元素是配置类的全限定名(如"com.example.MyConfig") - 返回的类会被 Spring 当作
@Configuration类处理(即使没加 @Configuration 也生效)
结合条件动态选择配置类
常见场景是根据环境、属性或是否存在某个类来决定加载哪套配置:
- 读取
Environment判断 profile:environment.acceptsProfiles("dev") - 检查 classpath 是否存在某个类:
ClassUtils.isPresent("org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration", getClass().getClassLoader()) - 读取
@EnableXxx注解的属性值(通过importingClassMetadata解析)
例如:一个 MyImportSelector 根据 @EnableMyFeature(enabled = true) 的 enabled 属性,决定是否导入 FeatureConfig.class。
注意 ImportSelector 的执行时机和限制
它在 ConfigurationClassPostProcessor 阶段早期执行,早于 BeanFactory 初始化,因此:
- 不能直接注入普通 Bean(如
@Autowired Service),但可以注入Environment、BeanFactory等基础设施 Bean - 若需更晚的上下文信息,考虑用
DeferredImportSelector(它会在所有@Configuration类解析完后才执行,支持按顺序或条件排序) - 返回的类名必须能被 ClassLoader 加载到,否则启动报错
完整示例结构
定义一个启用注解:@EnableMyModule → 元注解含 @Import(MyModuleImportSelector.class);MyModuleImportSelector 实现 ImportSelector,根据 importingClassMetadata 或 Environment 返回 {"com.example.MyModuleConfig"};MyModuleConfig 是标准 @Configuration 类,定义相关 Bean。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











