SpringBoot @Import 详解

SpringBoot 的 @Import 用于将指定的类实例注入之Spring IOC Container中。 

SpringBoot 提供了 三种使用 @Import 将 类实例注入至 Spring IOC Container中 的实例。

  • 直接注入
  • 实现 ImportBeanDefinitionRegistrar 接口 注入
  • 实现 ImportSelector 注入

一、 直接注入

 

  • Broker.java(无任何属性和实现)

    • package com.springBoot.entrance.importBean.direct;
      
      public class Broker {
      
      }
    • Customer.java(无任何属性和实现)

      package com.springBoot.entrance.importBean.direct;
      
      public class Customer {
      
      }
    • ImportDirect.java

      package com.springBoot.entrance.importBean.direct;
      
      import org.springframework.context.annotation.Import;
      import org.springframework.stereotype.Component;
      
      
      @Component
      @Import({Customer.class,Broker.class})
      /**
       *使用Import 将指定的类的实例注入至Spring 容器中
       */
      public class ImportDirect {
      
      }

      代码解读:使用 @Import({Customer.class,Broker.class}) 后 Customer 和 Broker类的实例将会被注入之Spring IOC Container中

    • App.java

      //import Direct 使用import 直接将指定的类实例注入至Spring 容器中
              System.out.println(context.getBean(ImportDirect.class));
              System.out.println(context.getBean(Customer.class));
              System.out.println(context.getBean(Broker.class));
    • 结果 
      这里写图片描述


 二、实现 ImportBeanDefinitionRegistrar 接口 注入

  • Forwards.java(无任何属性和实现)

    package com.springBoot.entrance.importBean.indirectImportBeanDefinitionRegistrar;
    
    public class Forwards {
    
    }
  • Security.java(无任何属性和实现)

    package com.springBoot.entrance.importBean.indirectImportBeanDefinitionRegistrar;
    
    public class Security {
    
    }
  • MyImportBeanDefinitionRegistrar.java

    package com.springBoot.entrance.importBean.indirectImportBeanDefinitionRegistrar;
    
    import org.springframework.beans.factory.support.BeanDefinitionBuilder;
    import org.springframework.beans.factory.support.BeanDefinitionRegistry;
    import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
    import org.springframework.core.type.AnnotationMetadata;
    
    /**
     * registerBeanDefinitions 方法中的参数 BeanDefinitionRegistry 可以往Spring IOC Container 中动态地装配Bean
     */
    public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
    
        public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
    
            //手动注入 Forwards 类的实例
            BeanDefinitionBuilder beanDef_forwards = BeanDefinitionBuilder.rootBeanDefinition(Forwards.class);
            registry.registerBeanDefinition("forwards", beanDef_forwards.getBeanDefinition());
    
            //手动注入 Security类的实例
            BeanDefinitionBuilder beanDef_security = BeanDefinitionBuilder.rootBeanDefinition(Security.class);
            registry.registerBeanDefinition("security", beanDef_security.getBeanDefinition());
        }
    
    }
  • App.java

    @Import(MyImportBeanDefinitionRegistrar.class)
    @Configuration
    public class App {
    
    
        public static void main(String[] args) throws Exception {
            ConfigurableApplicationContext context = SpringApplication.run(App.class, args);
    
            //实现ImportBeanDefinitionRegistrar 实现Bean的注入
            System.out.println(context.getBean(MyImportBeanDefinitionRegistrar.class));
            System.out.println(context.getBean(Forwards.class));
            System.out.println(context.getBean(Security.class));
    
        }
    
    
    }

三、 实现 ImportSelector 注入

  • Market.java(无任何属性或实现)

    package com.springBoot.entrance.importBean.indirectImportSelector;
    
    public class Market {
    
    }
  • Sales.java(无任何属性或实现)

    package com.springBoot.entrance.importBean.indirectImportSelector;
    
    public class Sales {
    
    }
  • EnableLogInfo.java

    package com.springBoot.entrance.importBean.indirectImportSelector;
    
    import java.lang.annotation.Documented;
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    
    import org.springframework.context.annotation.Import;
    
    
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.TYPE)
    @Documented
    @Import(MyImportSelector.class)
    /**
     *自定义Enable*
     *1.
     */
    public @interface EnableLogInfo {
    
        String[] name();
    
    
    }
  • MyImportSelector.java

    package com.springBoot.entrance.importBean.indirectImportSelector;
    
    import org.springframework.context.annotation.Import;
    import org.springframework.context.annotation.ImportSelector;
    import org.springframework.core.type.AnnotationMetadata;
    import org.springframework.stereotype.Component;
    
    @Component
    @Import(value = { MyImportSelector.class })
    @EnableLogInfo(name="onlySale")
    /**
     * Bean的批量注入 使用自定义 ImportSelector 须实现 ImportSelector
     * 接口,返回值必须是class全称测集合,该集合内的所有类都将被Spring IOC容器统一管理
     */
    public class MyImportSelector implements ImportSelector {
    
        public String[] selectImports(AnnotationMetadata importingClassMetadata) {
    
            System.out.println(importingClassMetadata.getAnnotationAttributes(EnableLogInfo.class.getName()).toString().contains("onlySale"));
    
            //获取自定的@EnableLogInfo 信息 如果包含 onlySale 则只注入Sales class 否则 注入 Sales 和 Market 两个类
            if (importingClassMetadata.getAnnotationAttributes(EnableLogInfo.class.getName()) != null
                    && importingClassMetadata.getAnnotationAttributes(EnableLogInfo.class.getName()).toString().contains("onlySale")) {
    
                return new String[] {Sales.class.getName() };
            }
    
            // 将指定的类
            return new String[] { Market.class.getName(), Sales.class.getName() };
        }
    
    }

    代码解读:此处使用了@Import注解和实现了 ImportSelector 来注入Bean

    代码逻辑:通过 实现 ImportSelector 获得 importingClassMetadata 对象,然后再由 importingClassMetadata 获得 我们自定的@EnableLogInfo 中的 值,如果 该值包含 onlySale 则 我们只装配Sale 类实例,否则 装配 Sale 和Market 两个类的实例。

你可能感兴趣的:(Spring,Spring,boot,Import,spring,boot,spring,java)