当前位置 主页 > 网站技术 > 代码类 >

    Spring中@Import的各种用法以及ImportAware接口详解

    栏目:代码类 时间:2019-10-14 09:03

    @Import 注解

    @Import注解提供了和XML中<import/>元素等价的功能,实现导入的一个或多个配置类。@Import即可以在类上使用,也可以作为元注解使用。

    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    public @interface Import {
    
      /**
       * {@link Configuration}, {@link ImportSelector}, {@link ImportBeanDefinitionRegistrar}
       * or regular component classes to import.
       */
      Class<?>[] value();
    
    }
    
    

    注解中只有一个value();。支持导入@Configuration标注的配置类,实现ImportSelector接口的类、实现ImportBeanDefinitionRegistrar接口的类和普通的@component类。

    作为元注解使用

    @Import可以作为元注解使用,可以在@Import的继承上封装一层。我的理解是,这样做不会对外(使用方)暴露我内部的具体实现细节。

    举个例子:例如@EnableAspectJAutoProxy注解。

    @Import(AspectJAutoProxyRegistrar.class)
    public @interface EnableAspectJAutoProxy {
    

    @EnableAspectJAutoProxy就是被@Import这个元注解所标志了,我们(程序员)通过使用@EnableAspectJAutoProxy来开启AspectJAutoProxy,而Spring底层是通过@Import导入相应的配置类来实现的。

    导入实现ImportSelector接口的类

    先来看一下ImportSelector接口,该接口中只有一个方法:

    public interface ImportSelector {
      String[] selectImports(AnnotationMetadata importingClassMetadata);
    }
    

    ImportSelector,输入选择器。该接口就是用来根据给定的条件,选择导入哪些配置类。

    举个例子:例如@EnableTransactionManagement注解。

    @Import(TransactionManagementConfigurationSelector.class)
    public @interface EnableTransactionManagement {
    

    在@EnableTransactionManagement注解中使用了@Import(TransactionManagementConfigurationSelector.class)注解,其中TransactionManagementConfigurationSelector类就是实现了ImportSelector接口。

    public class TransactionManagementConfigurationSelector extends AdviceModeImportSelector<EnableTransactionManagement> {
      @Override
      protected String[] selectImports(AdviceMode adviceMode) {
        switch (adviceMode) {
          case PROXY:
            return new String[] {AutoProxyRegistrar.class.getName(),
                ProxyTransactionManagementConfiguration.class.getName()};
          case ASPECTJ:
            return new String[] {
                TransactionManagementConfigUtils.TRANSACTION_ASPECT_CONFIGURATION_CLASS_NAME};
          default:
            return null;
        }
      }
    }
    

    方法的内部实现逻辑也很简单,就是根据不同的AdviceMode导入不同的配置类,来实现事务管理。

    导入实现ImportBeanDefinitionRegistrar接口的类

    ImportBeanDefinitionRegistrar接口中也只有一个方法:

    public interface ImportBeanDefinitionRegistrar {
      void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry);
    }
    

    该接口允许我们根据所给的注解元数据,按需注册额外的BeanDefinition。

    举个例子:例如@EnableAspectJAutoProxy注解。