@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配置类
  

 

   注意目录层次,要保证UserConfigStudentConfigDemoApplication的外层,否则,这两个配置类就会被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" };
    }
}

  

posted on 2020-06-07 10:13  溪水静幽  阅读(904)  评论(0)    收藏  举报