@Bean、@Primary、@ConditionalOnBean、@ConditionalOnMissingBean注解详解以及搭配使用

目录

1、@Bean        

2、@primary和@Qulifier

    @Primary

   @Qualifier

3、@ConditionalOnMissingBean

4、@ConditionalOnBean

5、以上注解的搭配使用


1、@Bean        

  • value:标注bean在IOC容器中的id属性,spring容器通过该值获取bean,value和name功能相同,只能存在一个
  • name:标注bean在IOC容器中的id属性,spring容器通过该值获取bean
  • initMethod:指定初始化方法
  • destoryMethod:指定销毁的方法

例如:

@Configuration
public class TestConfig {

    /**
    * name=demo,通过demo注册bean
    * initMethod在bean初始化时候调用init()方法
    * destroyMethod在bean生命周期结束销毁时调用destroy()方法,生命周期取决于bean的scope属性
    */
    @Bean(name = "demo",
          initMethod = "init",
          destroyMethod = "destroy")
    public Demo demo() {
        return new Demo();
    }
}


class Demo() {
    
    public Demo() {}    

    public void init(){
        System.out.println("我是初始化方法");
    }
    public void destroy() {
        System.out.println("我是销毁方法");
    }
    
}

2、@primary和@Qulifier

       当一个接口有两个或多个实现时,@primary@Qulifier都可以解决实现类的优先实现问题,区别点在于:

  • @Primary:在实现类上标注,标识该实现类优先选择
  • @Qulifier:在接口上标注,标识选择哪一个实现类

例如:

    @Primary

public Integer People{
    void declaration();
}

@Primary // 标识优先选择Man类进行实现
@Service
public class Man implements People{
    void declaration() {
        System.out.println("我是男生")
    }
}

@Service
public class Woman implements People{
    void declaration() {
        System.out.println("我是女生")
    }
}

public class test {
    @Autowired
    private People people;
    
    public static void main(String[] args){
        people.declaration();
    }
    
}

   @Qualifier

public interface People{
    void declaration();
}

@Service("man")
public class Man implements People{
    void declaration(){
       System.out.println("我是男生");
    }
}

@Service("woman")
@Bean(name = "woman")
public class WoMan implements People{
    void declaration(){
       System.out.println("我女生");
    }
}

public class test{
    @Qualifier("woman") // 标注选择woman的bean进行自动注入
    @Autowire
    private People people;

    public static void main(Strings[] args) {
        people.delcaration();
    }
}

3、@ConditionalOnMissingBean

        应用中不包含某个类时,对应的配置才生效,应用中包含该类的bean,那么二次注册同类型的bean的时候则会报错,一般该注解的使用会伴随着以下错误:

expected single matching bean but found 2 
(该错误是由于系统已经注册过被@ConditionalOnMissingBean的bean,
然后就在别的地方注册了相同类型的bean,会提示不允许出现两个bean)
或者
expected at least 1 bean which qualifies as autowire candidate
(由于配置不生效,导致注册bean失败)

        例子:

public class People{
    public String name;
    public String getName(){
        return this.name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public People(){}
    public People(String name) {
        this.name = name;
    }
}

@Configuration
public class TestConfig {
    @Bean(name = "man")
    public People man() {
        return new People("我是男生");
    }

    @ConditionalOnMissingBean(People.class)
    // 若应用中已经注册了上面的"man"bean,那么
    // 如果再注册该"woman"的同类型People的bean,那么则会
    // 报错:expected single matching bean but found 2......
    @Bean("woman")
    public People woMan() {
        return new People("我是女生");
    }
}

        

4、@ConditionalOnBean

        该注解与ConditionalOnMissingBean注解相反,检查应用中是否拥有某个bean,若有,则生效。否则报错,一般伴随着以下错误:

        ```

                expected at least 1 bean which qualifies as autowire candidate

        ```

        条件化依赖:

        

条件依赖

@ConditionalOnClass应用中包含某个类时,对应的配置才生效。
@ConditionalOnMissingClass  应用中不包含某个类时,对应的配置才生效
@ConditionalOnBeanSpring容器中存在指定class的实例对象时,对应的配置才生效
@ConditionOnMissingBeanSpring容器中不存在指定class的实例对象时,对应的配置才生效
@ConditionOnProperty指定参数的值符合要求时,对应配置才生效
@ConditionOnResource指定资源存在时,对应的配置才生效
@ConditionalOnWebApplication当前处于Web环境时(WebApplicationContext),对应的配置才生效
@ConditionalOnExpression指定参数的值符合要求时,对应的配置才生效
@ConditionalOnNotWebApplication当前处于非Web环境时,对应的配置才生效
先后顺序@AutoConfigureAfter在指定的Configuration类之后加载
@AutoConfigureBefore在指定的Configuration类之前加载
@AutoConfigrreOrder指定该configuration类的加载顺序,默认值0

5、以上注解的搭配使用

        


@Data
@NoArgsConstructor
@AllArgsConstructor
public class Pepple{
    Cat cat;  
}

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Cat{
    String name;
}
@Configuration
public class TestConfig{

    @Bean
    public Cat cat(
        return new Cat("我是一只小猫咪")
    )

    @Bean
    public People peopleo2(Cat cat){
        return new People(cat);
    }

    /**
    * 代表优先注册该bean,并检查是否容器中拥有bean"cat",
    * 若没有,配置失败,报错:expected at
    * least 1 bean which qualifies as autowire candidate
    * 以及检查容器中是否拥有people同类型的bean(例如上面的“people02”的
    * bean已经提前手动注册了),
    * 若有,则报错:expected single matching 
    * bean but found 2 :people,people02
    */
    @Bean(name = {"people"},
          destroyMethod = "destroy"
    )
    @Primary
    @ConditionalOnBean({Cat.class})
    @ConditionalOnMissBean(
        name = {"people"}
    ) 
    public People people(Cat cat){
        return new People(cat);
    }
}

ps:部分知识点参考了一些文章中的思想,若有侵犯,联系整改或删除,(查的太广,忘记了记下博客链接);

        文章中的代码并未经过测试,只是方便例子理解知识点!

  • 6
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值