美文网首页
Spring通过注解注入组件

Spring通过注解注入组件

作者: O_Neal | 来源:发表于2019-07-31 01:21 被阅读0次

    组件声明

    在类上声明 @Component、@Configuration、@RestController、@Service、@Repository 等注解,表示这个类需要被注入IoC容器。

    1、@Configuration 和 @Bean

    @Configuration 常用来和 @Bean 配合使用,来注入第三方组件。

    例子:注入 Druid 数据源

    @Configuration
    public class DruidConfig {
      @Bean
      @ConfigurationProperties(prefix = "spring.datasource")
      public DataSource druidDataSource() {
        return new DruidDataSource();
      }
    }
    

    2、FactoryBean

    通过实现接口 FactoryBean 来注入

    例子:利用 FactoryBean 注入 Dog

    // 实现 FactoryBean
    public class DogFactoryBean implements FactoryBean<Dog> {
    
      // 对象
      @Override
      public Dog getObject() throws Exception {
        return new Dog();
      }
    
      // 类型
      @Override
      public Class<?> getObjectType() {
        return Dog.class;
      }
    
      // 是否单例,true表示是单例
      @Override
      public boolean isSingleton() {
        return true;
      }
    }
    // 注入 DogFactoryBean
    @Configuration
    public class MyConfig {
      @Bean
      DogFactoryBean dog() {
        return new DogFactoryBean();
      }
    }
    

    通过名字 dog 可以获取容器中的 Dog 对象;如果想获取 DogFactoryBean 对象,可以用 &dog 来获取。

    3、@Import

    在类上声明,可以快速注入多个第三方的类,常配合 ImportSelector、ImportBeanDefinitionRegistrar 使用

    例子:注入 Dog、Cat 类
    方式 1:注解注入

    @Import({Dog.class, Cat.class})
    public class MyConfig {}
    

    方式 2:实现接口 ImportSelector

    // 实现 ImportSelector
    public class MyImport implements ImportSelector {
      @Override
      public String[] selectImports(AnnotationMetadata metadata) {
        return new String[]{"com.xxx.Dog", "com.xxx.Cat"};
      }
    }
    // 导入 MyImport
    @Import({MyImport.class})
    public class MyConfig {}
    

    方式 3:实现接口 ImportBeanDefinitionRegistrar

    // 实现 ImportBeanDefinitionRegistrar
    public class MyImportBean implements ImportBeanDefinitionRegistrar {
      @Override
      public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
        BeanDefinition dogBean = new RootBeanDefinition(Dog.class);
        registry.registerBeanDefinition("dog", dogBean);
        BeanDefinition catBean = new RootBeanDefinition(Cat.class);
        registry.registerBeanDefinition("cat", beanDefinitions);
      }
    }
    // 导入 MyImportBean
    @Import({MyImportBean.class})
    public class MyConfig {}
    

    4、@Conditional

    可以自定义满足条件后才注入组件。

    例子:当容器中存在 Dog 时,才注入 Cat

    // 实现 Condition
    public class MyCondition implements Condition {
      @Override
      public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        for (String name : Objects.requireNonNull(context.getBeanFactory()).getBeanDefinitionNames()) {
          if ("com.xxx.Dog".equals(name)) {
            return true;
          }
        }
        return false;
      }
    }
    // 按条件注入 Cat
    @Configuration
    public class MyConfig {
        @Conditional(MyCondition.class)
        @Bean
        Cat cat() {
            return new Cat();
        }
    }
    

    Springboot 提供了一些 @Conditional 的实现

    @ConditionalOnClass:存在该类时生效
    @ConditionalOnBean:存在该Bean是生效
    @ConditionalOnProperty:配置正确时生效
    @ConditionalOnResource:资源存在是生效
    

    5、其它注解

    Springboot 提供的配置生效顺序的注解

    @AutoConfigureAfter:在指定的配置类生效后再注入
    @AutoConfigureBefore:在指定的配置类生效后再注入
    

    相关文章

      网友评论

          本文标题:Spring通过注解注入组件

          本文链接:https://www.haomeiwen.com/subject/imsarctx.html