参考文献

@Import使用

1
2
3
4
5
6
7
8
9
10
11
12
13
// org.springframework.context.annotation.Import
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Import {

/**
* {@link Configuration @Configuration}, {@link ImportSelector},
* {@link ImportBeanDefinitionRegistrar}, or regular component classes to import.
*/
Class<?>[] value();

}
  • 允许通过它引入@Configuration标注的类,引入ImportSelector接口和ImportBeanDefinitionRegistrar接口的实现,也包括@Component注解的普通类。
  • @Import可以用来批量导入需要注册的各种类,如普通的类、配置类,完后完成普通类和配置类中所有bean的注册。

@Importvalue常见用法

  • value为普通类

  • value@Configuration标注的类

  • value@ComponentScan标注的类

  • valueImportBeanDefinitionRegistrar接口类型

    1. 定义ImportBeanDefinitionRegistrar接口实现类,在registerBeanDefinitions方法中使用registry来注册bean
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    public class MyImportBeanDefinitionRegistrar implements
    ImportBeanDefinitionRegistrar {

    @Override
    public void registerBeanDefinitions(AnnotationMetadata
    importingClassMetadata, BeanDefinitionRegistry registry) {
    //定义一个bean:Service1
    BeanDefinition service1BeanDinition =
    BeanDefinitionBuilder.genericBeanDefinition(Service1.class).getBeanDefinition();
    //注册bean
    registry.registerBeanDefinition("service1", service1BeanDinition);
    //定义一个bean:Service2,通过addPropertyReference注入service1
    BeanDefinition service2BeanDinition =
    BeanDefinitionBuilder.genericBeanDefinition(Service2.class).
    addPropertyReference("service1", "service1").
    getBeanDefinition();
    //注册bean
    registry.registerBeanDefinition("service2", service2BeanDinition);
    }
    }
  1. 使用@Import来导入步骤1中定义的类

  2. 使用步骤2中@Import标注的类作为AnnotationConfigApplicationContext构造参数创建spring容器

  3. 使用AnnotationConfigApplicationContext操作bean

  • valueImportSelector接口类型

    1. 定义ImportSelector接口实现类,在selectImports返回需要导入的类的名称数组

      1
      2
      3
      4
      5
      6
      7
      8
      9
      public class MyImportSelector implements ImportSelector { 
         @Override
         public String[] selectImports(AnnotationMetadata importingClassMetadata) {
             return new String[]{
                     Service1.class.getName(),
                     Module1Config.class.getName()
            };
       }
      }
    2. 使用@Import来导入步骤1中定义的类

    3. 使用步骤2中@Import标注的类作为AnnotationConfigApplicationContext构造参数创建spring容

    4. 使用AnnotationConfigApplicationContext操作bean

  • valueDeferredImportSelector接口类型

    • DeferredImportSelectorImportSelector的子接口,既然是ImportSelector的子接口,所以也可以通过@Import进行导入,这个接口和ImportSelector不同地方有两点
      • 延迟导入
        • 比如@Import的value包含了多个普通类、多个@Configuration标注的配置类、多个ImportSelector接口的实现类,多个ImportBeanDefinitionRegistrar接口的实现类,还有DeferredImportSelector接口实现类,此时spring处理这些被导入的类的时候,会将DeferredImportSelector类型的放在最后处理, 会先处理其他被导入的类,其他类会按照value所在的前后顺序进行处理。
      • 按序导入
        • 实现Order接口