admin管理员组文章数量:1584833
文章目录
- @Condition注解的介绍和举例说明
- @ConditionalOnBean和@ConditionalOnMissingBean
- 描述
- 举例说明
- 第一情况:在bean被注入的情况下
- 第二情况:在bean不被注入的情况下
- @ConditionalOnClass和@ConditionalOnMissingClass
- 描述
- 举例说明
- 第一情况:在bean被注入的情况下
- 第二情况:在bean不被注入的情况下
- 第三情况:指定一个项目中不存在的路径:
- @ConditionalOnResource
- 描述
- 举例说明
- 第一情况:文件在resources的一级目录下
- 第一情况:文件不在resources的一级目录下
- 第一情况:文件不在resources的目录下
- @ConditionalOnProperty
- 描述
- 举例说明
- 第一情况:文件存在,且内容与@ConditionalOnProperty括号中的描述一致,但matchIfMissing值为false。
- 第一情况:文件存在,不过内容与@ConditionalOnProperty括号中的描述不一致,但matchIfMissing值为true。
- @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的值,说明Bean类成功注入。
- @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类注入到容器中,还是很有必要学习和了解的。
版权声明:本文标题:Condition注解的介绍和举例说明 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://www.elefans.com/xitong/1727949060a1139255.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论