Condition注解的介绍和举例说明

@Condition注解的介绍和举例说明

@ConditionalOnBean和@ConditionalOnMissingBean

描述

@ConditionalOnBean和@ConditionalOnMissingBean:是指是否找到特定的bean才会进行一个匹配,两个的用法都一样,放在类或方法的上方
创建一个测试用的实体类Bean,并加上@Component注解让其自动注入bean

@Component
public class Bean {
}

这个是@ConditionalOnBean和@ConditionalOnMissingBean 注解使用的示意图

@Component
// 测试ConditionalOnBean
// @ConditionalOnMissingBean(Bean.class)
@ConditionalOnBean(Bean.class)
public class BeanFifth {
}

举例说明

第一情况:在bean被注入的情况下

1.@ConditionalOnBean

// 给创建的新的实体加上ConditionalOnBean(Bean.class)
@Component // 所有加上Condition条件注解的测试bean也得加上这个注解,否则也会报错
@ConditionalOnBean(Bean.class)
public class BeanFifth {
}

这是测试类的代码,利用grtBean()方法去获取被注入的bean的值

@SpringBootApplication
public class Main {
    public static void main(String[] args) {
        ApplicationContext run = SpringApplication.run(Main.class, args);
        Object bean = run.getBean("beanFifth");
        System.out.println(bean);
    }
}

@ConditionalOnBean结果截图:
程序正常启动,且红色方框中是通过getBean()得到的bean的值
程序正常启动,且红色方框中是通过getBean()得到的bean的值,说明Bean类成功注入。

  1. @ConditionalOnMissingBean
@Component
// 测试ConditionalOnMissingBean
 @ConditionalOnMissingBean(Bean.class)// 将@ConditionalOnBean(Bean.class)替换成@ConditionalOnMissingBean(Bean.class),测试类的代码不变。
// @ConditionalOnBean(Bean.class)
public class BeanFifth {
}

@ConditionalOnBean结果截图:
在这里插入图片描述
截图表示出现异常,内容为:Exception in thread “main” org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named ‘beanFifth’ available。说明添加了@ConditionalOnMissingBean(Bean.class)这个条件之后,原先被注入的Bean类现在没有丢失,所以就无法通过此条件注解将BeanFifth类注入,从而得不到BeanFifth的值。

第二情况:在bean不被注入的情况下

1.@ConditionalOnBean

// @Component  将Bean类上的这个注解注释掉,让其不被注入
public class Bean {
}
@Component
// 测试ConditionalOnBean
// @ConditionalOnMissingBean(Bean.class)
@ConditionalOnBean(Bean.class) // 留下@ConditionalOnBean(Bean.class)条件
public class BeanFifth {
}

@ConditionalOnBean结果截图:
在这里插入图片描述
将@Component在Bean类上的这个注解注释掉,让其不被注入,所以找不到Bean类,由此导致BeanFifth类不能被注入,所以报错。
2. @ConditionalOnMissingBean

@ConditionalOnBean结果截图:
在这里插入图片描述
因为找不到被注入进来的Bean类,所以MissingBean的条件达成,所以此时就可以将BeanFifth类注入,从而可以被getBean()方法获取到值

@ConditionalOnClass和@ConditionalOnMissingClass

描述

@ConditionalOnClass和@ConditionalOnMissingClass:是指是否找到特定的bean类的路径才会进行一个匹配,其中@ConditionalOnClass(name=“类的路径”)而@ConditionalOnMissingClass(“类的路径”)
这个是@ConditionalOnClass和@ConditionalOnMissingClass 注解使用的示意图

@Component
@ConditionalOnClass(name="org.example.bean.Bean")
// @ConditionalOnMissingClass("org.example.bean.Bean")
public class BeanFirst {
}

举例说明

第一情况:在bean被注入的情况下

1.@ConditionalOnClass

@Component
@ConditionalOnClass(name="org.example.bean.Bean")
// @ConditionalOnMissingClass("org.example.bean.Bean")
public class BeanFirst {
}

测试类代码:

@SpringBootApplication
public class Main {
    public static void main(String[] args) {
        ApplicationContext run = SpringApplication.run(Main.class, args);
        Object bean = run.getBean("beanFirst");
        System.out.println(bean);
    }

}

测试截图:
在这里插入图片描述
由截图内容得知,在改指定目录存在,满足该条件注解的条件,从而能将BeanFirst成功的注入,并通过getBean()方法获取到值。

2.@ConditionalOnMissingClass

@Component
// @ConditionalOnClass(name="org.example.bean.Bean")
@ConditionalOnMissingClass("org.example.bean.Bean")
public class BeanFirst {
}

测试截图:
在这里插入图片描述
由截图内容得知,在改指定目录存在,且Bean类被注入的情况下,不满足该条件注解的条件,从而不能将BeanFirst成功的注入,也因此获取不到Bean的值。

第二情况:在bean不被注入的情况下

1.@ConditionalOnClass

public class Bean {
}
@Component
@ConditionalOnClass(name="org.example.bean.Bean")
// @ConditionalOnMissingClass("org.example.bean.Bean")
public class BeanFirst {
}

测试截图:
在这里插入图片描述
由截图内容得知,在改指定目录存在,且Bean类不被注入的情况下,也能满足该条件注解的条件,从而能将BeanFirst成功的注入,并通过getBean()方法获取到值。

2.@ConditionalOnMissingClass

@ConditionalOnMissingClass("org.example.bean.Bean")
public class BeanFirst {
}

**加粗样式**
由两个红色框框的内容表示,这个Bean的路径是实际存在的,即使Bean类没有被注入,但由于它的路径存在,就不满足@ConditionalOnMissingClass(“org.example.bean.Bean”)的条件,所以BeanFirst类无法被注入。

第三情况:指定一个项目中不存在的路径:

在这里插入图片描述
由截图可知:红色框中不存在蓝色框中的路径下的Bean34U类。
1.@ConditionalOnClass

@Component
@ConditionalOnClass(name="org.example.bean.Bean34U")
// @ConditionalOnMissingClass("org.example.bean.Bean34U")
public class BeanFirst {
}

测试截图:
在这里插入图片描述
由于指定的org.example.bean.Bean34U不存在,所以不满足@ConditionalOnClass()的条件

2.@ConditionalOnMissingClass

@Component
// @ConditionalOnClass(name="org.example.bean.Bean34U")
@ConditionalOnMissingClass("org.example.bean.Bean34U")
public class BeanFirst {
}

测试截图:
在这里插入图片描述
由于找不到org.example.bean.Bean34U,因此满足@ConditionalOnMissingClass的条件,从而能够将BeanFirst类注入。

@ConditionalOnResource

描述

@ConditionalOnResource:指在resources包下是否找到指定的文件资源,不管资源里是否有内容,而且如果一个文件是由多层结构的,需要将前面的也加上,比如如下情况:
在这里插入图片描述
其中spring.factories是在META-INF包下创建的,所以引用它的时候就得写成:“META-INF/spring.factories”,而application.yml文件就直接写文件名就行。

举例说明

本处的测试,我只做文件名正确的情况的测试,文件名错误的测试你们可以自己下去试试。

第一情况:文件在resources的一级目录下

用法:@ConditionalOnResource(resources=“文件名称”)

@Component
@ConditionalOnResource(resources="application.yml")
public class BeanSecond {
}

测试截图:
在这里插入图片描述
由于application.yml文件在resources包的一级目录下,且文件名正确,所以此时满足@ConditionalOnResource(resources=“application.yml”)的条件,因此能将BeanSecond类注入到容器中。

第一情况:文件不在resources的一级目录下
@Component
@ConditionalOnResource(resources="spring.factories")
public class BeanSecond {
}

测试截图
在这里插入图片描述
由图示可知,当文件的路径和@ConditionalOnResource的括号中的内容不是一个路径时,会出现报错,从而不会将BeanSecond类注入到容器中。
当我们将路径和右边的路径一致时,就可以将BeanSecond类注入到容器中。如下图:
在这里插入图片描述

第一情况:文件不在resources的目录下
@Component
@ConditionalOnResource(resources="build.gradle")
public class BeanSecond {
}

测试截图:
在这里插入图片描述
图中蓝色的文件build。gradle在项目中存在,但并不在resources包的一级目录下,所以不满足@ConditionalOnResource(resources=“build.gradle”)的条件,因此无法将BeanSecond注入到容器中。

@ConditionalOnProperty

描述

@ConditionalOnProperty:指是否存在指定的环境;
用法:@ConditionalOnProperty(prefix = “”,name = “”,havingValue = “”,matchIfMissing = false)

  • prefix:指配置文件的前缀;
  • name:指配置文件的名称;
  • havingValue:指与配文件对应的值;
  • matchIfMissing:指属性存在的情况,会优先考虑该值的状态,默认情况下,该值为false。
    举个例子:application.yml文件的内容如下:
    server: port: 8080
    这样的话 prefix=“server”,name=“port”,havingValue=“8080”

举例说明

本次测试的状况也很多,我在这测两种比较常见的状况,剩下的自己测吧。

第一情况:文件存在,且内容与@ConditionalOnProperty括号中的描述一致,但matchIfMissing值为false。

在这里插入图片描述

@Component
@ConditionalOnProperty(prefix = "server",name = "port",
havingValue = "8080",matchIfMissing = false)
public class BeanForth {
}

测试截图:
在这里插入图片描述
虽然matchIfMissing值为false,但由于前面的内容和配置文件的内容时一致的,这个时候,@ConditionalOnProperty就不会去考虑matchIfMissing值,而是认为前面三个的值已经达到条件,就会将BeanForth进行注入。

第一情况:文件存在,不过内容与@ConditionalOnProperty括号中的描述不一致,但matchIfMissing值为true。

在这里插入图片描述

@Component
@ConditionalOnProperty(prefix = "server",name = "port",
havingValue = "8080",matchIfMissing = true)
public class BeanForth {
}

测试截图:
在这里插入图片描述
由截图可知,尽管application.yml文件的内容和@ConditionalOnProperty(prefix = “server”,name = “port”,havingValue = “8080”),不能成功的对应上,但因为matchIfMissing值为true,@ConditionalOnProperty就会以matchIfMissing值为true为条件匹配的标准,从而认为能够达到条件,因此能将BeanForth类注入到容器中。

@Condition注解的总结

本博客只列出了一些比较常用的条件注解,其他的可以自己再去补充补充,了解一下具体的使用环境,以及自己也动手熟悉熟悉具体的用法和可用的场景。条件注解可以帮助我们在一些特定的场景将需要的bean类注入到容器中,还是很有必要学习和了解的。

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值