当前位置: 首页 > news >正文

java getbean不同实现_Spring Boot 2 实战:根据条件来自动配置不同逻辑的Bean

79b14702b9753ff68cb25f5cb67452ef.png

1. 前言

我们经常会有根据条件来加载不同的接口。比如你查询目录下文件列表, Windows 下你会用 CMD 的 dir 命令,而 Linux 下你会使用 ls 命令。 熟悉 Spring Boot 自动配置的也知道 Spring Boot 能根据不同的实际情况启用不同的配置。这就是@Conditional注解在发挥作用。 该注解指定了在什么条件下创建 Bean 进行配置。

2. @Conditional 注解

Spring Boot 包含多个 @Conditional 注释,可以在@Configuration注解的类和@Bean注解方法中使用。@Conditional类型的注解,可以注解在类上,可以注解在Bean方法上,可以允许基于Spring Environment属性包含配置,可以仅允许在存在特定资源时包含配置。也可自定义,接下来我们来熟悉一下 Spring Boot 提供的一些具体的条件注解。

2.1 Class Conditions

@ConditionalOnClass和@ConditionalOnMissingClass 两个在类上的注解:

判断指定的类是否存在来构建自动配置,也可使用name属性名来指定类名。

2.2 Bean Conditions

@ConditionalOnBean和@ConditionalOnMissingBean 两个在 Bean 方法上的注解:

判断指定的 Bean 是否存在来构建自动配置,可以使用value属性来按类型或名称(id)指定 Bean, 可以使用search属性指定 ApplicationContext 层次结构来搜索Bean。

@Configuration

public class MyAutoConfiguration {

@Bean

@ConditionalOnMissingBean

public MyService myService() { ... }

}

要添加注意添加 Bean 时的顺序,官方建议在自动配置类上仅使用 @ConditionalOnBean和@ConditionalOnMissingBean注释,因为可以保证这些注释在添加用户定义的Bean后执行。

@ConditionalOnBean和@ConditionalOnMissingBean注解作用在@Configuration注释的类上,等同于在作用在每个包含@Bean的方法上。

2.3 Property Conditions

@ConditionalOnProperty注解可以基于Spring Environment属性包含的配置进判断,再决定自动配置的执行,使用 prefix 和 name 属性指定应检查的属性。默认情况下,匹配存在且不等于false的任何属性。 您还可以使用havingValue和matchIfMissing属性创建更高级的检查。

2.4 Resource Conditions

@ConditionalOnResource注释仅允许在存在特定资源时执行自动配置。 可以使用常用的 Spring 约定来指定资源,如以下示例所示:file:/home/user/test.dat。

2.5 Web Application Conditions

@ConditionalOnWebApplication和@ConditionalOnNotWebApplication注解用于判断应用程序是否为Web应用程序,Web应用程序是使用Spring WebApplicationContext,定义会话范围或具有StandardServletEnvironment的任何应用程序。

2.6 SpEL Expression Conditions

@ConditionalOnExpression注解允许根据SpEL表达式的结果来执行配置。

3. 自定义 Condition

如果上面几种都不能满足你的需要。那么我们可以通过实现Condition接口,并重写其matches方法来构造判断条件。

1.实现 Condition 接口来定义判断条件

//Windows系统的判断条件

import org.springframework.context.annotation.Condition;

import org.springframework.context.annotation.ConditionContext;

import org.springframework.core.type.AnnotatedTypeMetadata;

public class WindowsCondition implements Condition {

@Override

public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {

return context.getEnvironment().getProperty("os.name").contains("Windows");

}

}

//Linux系统的判断条件

import org.springframework.context.annotation.Condition;

import org.springframework.context.annotation.ConditionContext;

import org.springframework.core.type.AnnotatedTypeMetadata;

public class LinuxCondition implements Condition {

@Override

public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {

return context.getEnvironment().getProperty("os.name").contains("Linux");

}

}

2.实现不同系统下的Bean类

//接口

public interface ListService {

public String showListCmd();

}

//Windows下的实现类

public class WindowsListServiceImpl implements ListService {

@Override

public String showListCmd() {

return "dir";

}

}

//Linux下的实现类

public class LinuxListServiceImpl implements ListService {

@Override

public String showListCmd() {

return "ls";

}

}

3.配置类

@Conditional注解调用条件判断的类并根据返回的结果来创建Bean

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Conditional;

import org.springframework.context.annotation.Configuration;

@Configuration

public class ConditionConfig {

@Bean

@Conditional(WindowsCondition.class)

public ListService windowsListService() {

return new WindowsListServiceImpl();

}

@Bean

@Conditional(LinuxCondition.class)

public ListService linuxListService() {

return new LinuxListServiceImpl();

}

}

4.运行类

@RunWith(SpringRunner.class)

@SpringBootTest

public class SecurityLearningApplicationTests {

@Resource

private ListService listService ;

@Resource

private ApplicationContext context;

public void testCondition(){

System.out.println(context.getEnvironment().getProperty("os.name")

+ "系统下的列表命令:"

+ listService.showListCmd());

}

}

4. 总结

今天我们对 Spring Boot 中的 Condition 条件判断注入进行了系统性的了解。不仅对 Spring Boot 提供的一些开箱即用的 Condition 进行了学习,还实现了自定义的 Condition 。如果你要对 Spring Boot 的自动配置深入学习或者根据业务来灵活定制,就必须对 Condition 进行系统性的学习。

关注公众号:Felordcn获取更多资讯

相关文章:

  • 孝感 java_孝感java工资一般多少,孝感java工资待遇,孝感java工资待遇到多少
  • java struct2拦截器_Java struts2 拦截器 interceptors
  • JAVA安卓4.4.4_Android源码4.4.4_r1下载和编译
  • java 设置listview单元格颜色_动态改变Listview的item背景颜色和item中字体的颜色
  • 最长递增子序列 java_动态规划深入6 最长递增子序列
  • yml mysql参数_yml配置--给参数设置默认值
  • ant java eclipse_(转)Eclipse中使用Ant
  • java json merge_JavaScript 如何合并两个Json对象
  • java setselectionend_Java Gallery.setSelection方法代码示例
  • stringbuffer java API_StringBuffer类
  • jasperreport java数据_ireport5.6.0+jasperreports 使用java对象做为数据源导出excel或者Pdf...
  • 与时间相关的java源码_JAVA的Date类与Calendar类
  • Java修改文件扩展属性_扩展PropertyPlaceholderConfigurer对prop文件中的属性加密(修正1)...
  • java定义显性构造函数_Java基础之三、类的特性和接口
  • mysql用其他表更新_mysql用一个表更新另一个表
  • JS中 map, filter, some, every, forEach, for in, for of 用法总结
  • [deviceone开发]-do_Webview的基本示例
  • ➹使用webpack配置多页面应用(MPA)
  • angular2开源库收集
  • flutter的key在widget list的作用以及必要性
  • GitUp, 你不可错过的秀外慧中的git工具
  • Mithril.js 入门介绍
  • MySQL QA
  • mysql常用命令汇总
  • Node 版本管理
  • PHP面试之三:MySQL数据库
  • Python实现BT种子转化为磁力链接【实战】
  • QQ浏览器x5内核的兼容性问题
  • yii2中session跨域名的问题
  • 大主子表关联的性能优化方法
  • 关键词挖掘技术哪家强(一)基于node.js技术开发一个关键字查询工具
  • 开放才能进步!Angular和Wijmo一起走过的日子
  • 类orAPI - 收藏集 - 掘金
  • 微服务核心架构梳理
  • kubernetes资源对象--ingress
  • Play Store发现SimBad恶意软件,1.5亿Android用户成受害者 ...
  • ​LeetCode解法汇总2696. 删除子串后的字符串最小长度
  • #考研#计算机文化知识1(局域网及网络互联)
  • #控制台大学课堂点名问题_课堂随机点名
  • (1)Map集合 (2)异常机制 (3)File类 (4)I/O流
  • (16)UiBot:智能化软件机器人(以头歌抓取课程数据为例)
  • (C语言)求出1,2,5三个数不同个数组合为100的组合个数
  • (附源码)ssm高校实验室 毕业设计 800008
  • (附源码)ssm基于jsp高校选课系统 毕业设计 291627
  • (附源码)流浪动物保护平台的设计与实现 毕业设计 161154
  • (利用IDEA+Maven)定制属于自己的jar包
  • (亲测有效)解决windows11无法使用1500000波特率的问题
  • (淘宝无限适配)手机端rem布局详解(转载非原创)
  • (转)EOS中账户、钱包和密钥的关系
  • (转)ObjectiveC 深浅拷贝学习
  • (转)setTimeout 和 setInterval 的区别
  • (转载)虚幻引擎3--【UnrealScript教程】章节一:20.location和rotation
  • .gitattributes 文件
  • .NET Core IdentityServer4实战-开篇介绍与规划
  • .Net Core与存储过程(一)