@Import 与@ImportSelector
@Import注解的作用是导入一个配置Configuration类,什么地方会用到它?工程中也不会使用这个注解去导入配置,都是新建一个类xxxConfiguration.java,然后直接在类里边把所有的Bean组件都给声明。
当配置类xxxxxConfig不在@SpringBootApplication所在包及其子包下时,还能被装配进去吗?答案是不能,因为不在springboot默认扫描范围内。
解决办法有二种:
- 1、使用
@ComponentScan("com.**")注解一句话搞定 - 2、使用
@Import注解引入
ImportSelector
ImportSelector将允许根据条件动态选择想导入的配置类,具有动态性。ImportSelector使用时,要创建一个类实现ImportSelector接口,并重写其中的String[] selectImports(AnnotationMetadata importingClassMetadata);方法。 想实现这样一个功能,我们创建一个
CustomImportSelector类,当使用CustomImportSelector的元素是类时,我们返回UserConfig配置类,当使用CustomImportSelector的元素是接口时,我们返回StudentConfig配置类
注意目录层次,要保证UserConfig和StudentConfig在DemoApplication的外层,否则,这两个配置类就会被spring默认解析到。
@Configuration public class UserConfig { @Bean public User getUser() { return new User(); } } @Configuration public class StudentConfig { @Bean public Student getStudent() { return new Student(); } } @SpringBootApplication // 1、很明显,这里CustomImportSelector修饰的是一个类,我们将会返回UserConfig @Import(CustomImportSelector.class) public class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } } public class CustomImportSelector implements ImportSelector { /** * importingClassMetadata:被修饰的类注解信息 */ @Override public String[] selectImports(AnnotationMetadata importingClassMetadata) { // 注意,自定义注解这里是拿不到的 System.out.println(importingClassMetadata.getAnnotationTypes()); // 如果被CustomImportSelector导入的组件是类,那么就实例化UserConfig if (!importingClassMetadata.isInterface()) { return new String[] { "com.example.UserConfig" }; } // 此处不要返回null return new String[] { "com.example.StudentConfig" }; } }
立志如山 静心求实
浙公网安备 33010602011771号