• Spring的@Import注解简单介绍


    Spring的@Import注解

    作用

    1. 将没有使用@Component注解的普通class加入到Spring容器, 由Spring管理
    2. 导入一个Configuration类(比如你想组合多个Java Config类到一个Java Config类, 或者你引入的第三方jar包中的Java Config类没在你SpringBoot程序的子包下, 即没有被扫描进Spring容器)
    3. 通过实现了ImportSelector接口的类, 导入多个class到Spring容器(SpringBoot的自动装配@EnableAutoConfiguration)
    4. 通过实现ImportBeanDefinitionRegistrar接口的方式(MyBatis整合Spring: MapperScannerRegistrar.java和@MapperScan注解)

    示例

    1. 将普通Class加入到Spring容器

    普通class

    没有使用@Component注解, 有一个实例方法.

    /**
     * 一个普通的class, 没有被打上{@link org.springframework.stereotype.Component}注解, 后续使用@Import导入到Spring容器
     *
     * @author rhyme
     */
    @Slf4j
    public class ClassWithoutComponentAnnotation {
      public boolean methodA() {
        log.info("ClassWithoutComponentAnnotation对象的**实例方法**methodA被调用");
        return true;
      }
    }
    

    2. @Import Java Config

    将该类也和上面一样, 由@Import引入就行

    @Configuration
    public class ClassWithConfigurationAnnotation {
      @Bean
      public DemoClass demoClass() {
        return new DemoClass();
      }
    }
    

    3. 实现了ImportSelector接口的类, 导入多个class到Spring容器

    实现了ImportSelector接口的类

    /** @author rhyme */
    public class ClassImplementsImportSelector implements ImportSelector {
    
      @Override
      public String[] selectImports(AnnotationMetadata importingClassMetadata) {
        return new String[] {
          "java.basic.demos.springannotation.Import.classimplementsimportselector.ClassA",
          "java.basic.demos.springannotation.Import.classimplementsimportselector.ClassB"
        };
      }
    }
    

    各种@EnableXXX注解, 比如SpringBoot源码中的@EnableAutoConfiguration@EnableCircuitBreaker

    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Inherited
    @AutoConfigurationPackage
    @Import(AutoConfigurationImportSelector.class)
    public @interface EnableAutoConfiguration {
    
     String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
    
     /**
      * Exclude specific auto-configuration classes such that they will never be applied.
      * @return the classes to exclude
      */
     Class<?>[] exclude() default {};
    
     /**
      * Exclude specific auto-configuration class names such that they will never be
      * applied.
      * @return the class names to exclude
      * @since 1.3.0
      */
     String[] excludeName() default {};
    
    }
    
    /**
     * Annotation to enable a CircuitBreaker implementation.
     * https://martinfowler.com/bliki/CircuitBreaker.html
     * @author Spencer Gibb
     */
    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Inherited
    @Import(EnableCircuitBreakerImportSelector.class)
    public @interface EnableCircuitBreaker {
    
    }
    

    4. 实现ImportBeanDefinitionRegistrar接口的方式

    实现了ImportBeanDefinitionRegistrar接口, 注册自己的bean

    /** @author rhyme */
    public class ClassImplementImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
    
      @Override
      public void registerBeanDefinitions(
          AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        RootBeanDefinition root = new RootBeanDefinition(ClassC.class);
        registry.registerBeanDefinition("classC", root);
      }
    }
    

    MyBatis整合Spring源码

    /**
     * A {@link ImportBeanDefinitionRegistrar} to allow annotation configuration of
     * MyBatis mapper scanning. Using an @Enable annotation allows beans to be
     * registered via @Component configuration, whereas implementing
     * {@code BeanDefinitionRegistryPostProcessor} will work for XML configuration.
     *
     * @author Michael Lanyon
     * @author Eduardo Macarron
     * 
     * @see MapperFactoryBean
     * @see ClassPathMapperScanner
     * @since 1.2.0
     */
    public class MapperScannerRegistrar implements ImportBeanDefinitionRegistrar, ResourceLoaderAware {
    
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.TYPE)
    @Documented
    @Import(MapperScannerRegistrar.class)
    public @interface MapperScan {
    

    5. 使用@Import搭配@Configuration导入到Spring容器

    /**
     * @Import注解, 搭配@Configuration, 见ImportConfigTest.java<br>
     * 1. 将没有使用@Component注解的普通class加入到Spring容器, 由Spring管理<br>
     * 2. 导入一个Configuration类 <br>
     * 3. 通过实现了ImportSelector接口的类, 导入多个class到Spring容器(**SpringBoot的自动装配@EnableAutoConfiguration**) <br>
     * 4. 通过实现ImportBeanDefinitionRegistrar接口的方式(MyBatis整合Spring:MapperScannerRegistrar.java和@MapperScan注解)
     *
     * @author rhyme
     */
    @Configuration
    @Import({
      ClassWithoutComponentAnnotation.class,
      ClassWithConfigurationAnnotation.class,
      ClassImplementsImportSelector.class,
      ClassImplementImportBeanDefinitionRegistrar.class
    })
    public class ImportConfig {}
    

    6. 测试

    @RunWith(SpringRunner.class)
    @SpringBootTest
    public class ImportConfigTest {
      @Autowired private ClassWithoutComponentAnnotation classWithoutComponentAnnotation;
      @Autowired private DemoClass demoClass;
      @Autowired private ClassA classA;
      @Autowired private ClassB classB;
      @Autowired private ClassC classC;
    
      /** 通过@Autowired获取@Import的类 */
      @Test
      public void importClass2SpringContainerTest() {
        Assert.assertNotNull(classWithoutComponentAnnotation);
        Assert.assertNotNull(demoClass);
        Assert.assertNotNull(classA);
        Assert.assertNotNull(classB);
        Assert.assertNotNull(classC);
      }
    }
    
  • 相关阅读:
    OSPF协议原理
    TCPDUMP抓包方法
    latex:画图
    FrankWolf算法
    Three20 Navigation 迁移到TTTableViewController一直显示加载中的解决办法
    ipa在iTunes中没有图标
    iPhone应用提交AppStore时Application failed codesign verification问题的解决
    XCode4.5 iOS6 SDK 提交AppStore Validate各种错误的解决
    1.forEach():遍历数组,并为每个元素调用传入的函数; 举例:
    CSS实现单行、多行文本溢出显示省略号(…)
  • 原文地址:https://www.cnblogs.com/theRhyme/p/13887223.html
Copyright © 2020-2023  润新知