Spring条件注解@Conditional
@Conditional是Spring4新提供的注解,它的作用是根据某个条件创建特定的Bean,通过实现Condition接口,并重写matches接口来构造判断条件。总的来说,就是根据特定条件来控制Bean的创建行为,这样我们可以利用这个特性进行一些自动的配置。
本文将分为三大部分,@Conditional源码的介绍、Condition的使用示例和@Conditional的扩展注解的介绍。
一、@Conditional的源码
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Conditional {
/**
* All {@link Condition Conditions} that must {@linkplain Condition#matches match}
* in order for the component to be registered.
*/
Class<? extends Condition>[] value();
}
从源码中可以看到,@Conditional注解可以用在类和方法上,需要传入一个实现了Condition接口class数组。
二、代码示例
下面将以不同的操作系统为条件,通过实现Condition接口,并重写其matches方法来构造判断条件。若在Windows系统下运行程序,则输出列表命令为dir;若在Linux系统下运行程序,则输出列表命令为ls。
1.判断条件类的定义
(1).判断Windows的条件
package com.study.day01; import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata; /**
* @Auther: lifq
* @Description:
*/
public class WindowsCondition implements Condition {
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
return context.getEnvironment().getProperty("os.name").contains("Windows");
}
}
(2).判断Linux的条件
package com.study.day01; import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata; /**
* @Auther: lifq
* @Description:
*/
public class LinuxCondition implements Condition {
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
return context.getEnvironment().getProperty("os.name").contains("Linux");
}
}
2.不同系统下的Bean的类
(1).接口代码
package com.study.day01; import org.springframework.stereotype.Service; /**
* @Auther: lifq
* @Description:
*/
public interface ListService { public String showListCmd(); }
(2).Windows实现类代码
package com.study.day01; /**
* @Auther: lifq
* @Description:
*/
public class WindowsService implements ListService {
public String showListCmd() {
return "dir";
}
}
(3).Linux实现类代码
package com.study.day01; /**
* @Auther: lifq
* @Description:
*/
public class LinuxService implements ListService {
public String showListCmd() {
return "ls";
}
}
3.配置类
package com.study.day01; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration; /**
* @Auther: lifq
* @Description:
*/
@Configuration
public class Config { @Bean
@Conditional(WindowsCondition.class)
public ListService window() {
return new WindowsService();
} @Bean
@Conditional(LinuxCondition.class)
public ListService linux() {
return new LinuxService();
}
}
4.运行类
package com.study.day01; import org.springframework.context.annotation.AnnotationConfigApplicationContext; /**
* @Auther: lifq
* @Description:
*/
public class Main01 { public static void main (String []args) { AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(Config.class); ListService listService = applicationContext.getBean(ListService.class); System.out.println(applicationContext.getEnvironment().getProperty("os.name") + "系统下的列表命令为:" + listService.showListCmd());
}
}
我的是Windows操作系统,输出结果为dir,运行截图如下:
运行截图

@Conditional注解例子演示完成,有问题欢迎留言沟通哦!
完整源码地址:https://github.com/suisui2019/springboot-study
三、@Conditional的扩展注解
@ConditionalOnBean:仅仅在当前上下文中存在某个对象时,才会实例化一个Bean。
@ConditionalOnClass:某个class位于类路径上,才会实例化一个Bean。
@ConditionalOnExpression:当表达式为true的时候,才会实例化一个Bean。
@ConditionalOnMissingBean:仅仅在当前上下文中不存在某个对象时,才会实例化一个Bean。
@ConditionalOnMissingClass:某个class类路径上不存在的时候,才会实例化一个Bean。
@ConditionalOnNotWebApplication:不是web应用,才会实例化一个Bean。
@ConditionalOnBean:当容器中有指定Bean的条件下进行实例化。
@ConditionalOnMissingBean:当容器里没有指定Bean的条件下进行实例化。
@ConditionalOnClass:当classpath类路径下有指定类的条件下进行实例化。
@ConditionalOnMissingClass:当类路径下没有指定类的条件下进行实例化。
@ConditionalOnWebApplication:当项目是一个Web项目时进行实例化。
@ConditionalOnNotWebApplication:当项目不是一个Web项目时进行实例化。
@ConditionalOnProperty:当指定的属性有指定的值时进行实例化。
@ConditionalOnExpression:基于SpEL表达式的条件判断。
@ConditionalOnJava:当JVM版本为指定的版本范围时触发实例化。
@ConditionalOnResource:当类路径下有指定的资源时触发实例化。
@ConditionalOnJndi:在JNDI存在的条件下触发实例化。
@ConditionalOnSingleCandidate:当指定的Bean在容器中只有一个,或者有多个但是指定了首选的Bean时触发实例化。
推荐阅读
1.Spring Boot入门-快速搭建web项目
2.Spring Boot 2.X 整合Redis
3.Spring Boot 2.X 如何优雅的解决跨域问题?
4.Spring Boot 2.X 如何添加拦截器?
5.Spring Boot 2.X 集成spring session实现session共享
6.Redis Cluster搭建高可用Redis服务器集群
7.为什么单线程的Redis这么快?
8.一篇文章搞定SpringMVC参数绑定
9.SpringMVC+Mybatis 如何配置多个数据源并切换?
限时领取免费Java相关资料,涵盖了Java、Redis、MongoDB、MySQL、Zookeeper、Spring Cloud、Dubbo/Kafka、Hadoop、Hbase、Flink等高并发分布式、大数据、机器学习等技术。
资料传送门: https://mp.weixin.qq.com/s/u2b_NVNuMuAPE0w4lc45fw
关注下方公众号即可免费领取:
Spring条件注解@Conditional的更多相关文章
- Spring Boot实战笔记(八)-- Spring高级话题(条件注解@Conditional)
一.条件注解@Conditional 在之前的学习中,通过活动的profile,我们可以获得不同的Bean.Spring4提供了一个更通用的基于条件的Bean的创建,即使用@Conditional注解 ...
- [读书笔记] 二、条件注解@Conditional,组合注解,元注解
一.条件注解@Conditional,组合注解,元注解 1. @Conditional:满足特定条件创建一个Bean,SpringBoot就是利用这个特性进行自动配置的. 例子: 首先,两个Condi ...
- Spring_总结_04_高级配置(二)_条件注解@Conditional
一.前言 本文承接上一节:Spring_总结_04_高级配置(一)之Profile 在上一节,我们了解到 Profile 为不同环境下使用不同的配置提供了支持,那么Profile到底是如何实现的呢?其 ...
- 条件注解@Conditional
通过活动的profile,可以获得不同的Bean.Spring4提供了一个更通用的基于条件的Bean的创建,即使用@Conditonal注解 @Conditional根据满足某一个特定条件创建一个特定 ...
- springboot自动装配(3)---条件注解@Conditional
之前有说到springboot自动装配的时候,都是去寻找一个XXXAutoConfiguration的配置类,然而我们的springboot的spring.factories文件中有各种组件的自动装配 ...
- Spring知识点回顾(06)Profile 和 条件注解 @Conditional
1.设定环境中的active profiles 如:DispatcherServerlet的init-param spring.profiles.active=production spring.pr ...
- SpringBoot条件注解@Conditional
最近项目中使用到了关于@Conditional注解的一些特性,故写此文记录一下 @Conditional是啥呀? @Conditional注解是个什么东西呢,它可以根据代码中设置的条件装载不同的bea ...
- 通过条件注解@Conditional细粒度的选择bean实例
在进行spring进行开发时,当某个接口有多种实现方式并且我们只想让一种生效时,比如声明如下一个接口和两个实现: public interface LanggageService { String s ...
- JavaEE开发之Spring中的条件注解组合注解与元注解
上篇博客我们详细的聊了<JavaEE开发之Spring中的多线程编程以及任务定时器详解>,本篇博客我们就来聊聊条件注解@Conditional以及组合条件.条件注解说简单点就是根据特定的条 ...
随机推荐
- Linux htop 使用
引言 一般大家查看进程相关信息常用的命令是 top,之前接触并使用 htop,觉得比较好用,它算是 top 的增强版,这里重新记录下. htop 简介 NAME htop - interactive ...
- 渐进式web应用开发---service worker (二)
阅读目录 1. 创建第一个service worker 及环境搭建 2. 使用service worker 对请求拦截 3. 从web获取内容 4. 捕获离线请求 5. 创建html响应 6. 理解 ...
- java日期在今天的基础上加一个月。并计算时间相差天数
Calendar calendar = Calendar.getInstance(); calendar.setTime(date); calendar.add(Calendar.MONTH, 1); ...
- Kafka Eagle V1.3.4更新预览
1.概述 Kafka Eagle是一款开源的Kafka集群监控系统,源代码托管在Github.目前Kafka Eagle已更新到V1.3.4版本,域名已经统一更新为http://www.kafka-e ...
- 自我救赎 → 利用 IDEA 和 Spring Boot 搭建 SSM
前言 开心一刻 儿子读高中放学回来了,一向不管他学习的我突然来了兴趣,想看看他的学习他的状况,抄起他的数学习题看了起来,当看到 1 x 2 x 3 x 4 x 5 x 6 x 7 x 8 x 9 x ...
- redis可视化客户端
1. 场景描述 redis安装完成后,使用命令行看还是有点不方便,github上有开源的redis可视化客户端,很好用,介绍下. 2.解决方案 使用redisclient客户端,来操作redis. 2 ...
- Git使用小技巧之免密登录
想要获取更多文章可以访问我的博客 - 代码无止境. 小代同学在使用Git的过程中发现,每次向远程仓库推送代码的时候都需要输入账号密码.做为一个程序员,多多少少都会有偷懒的思维.那么如何才能避免每次都要 ...
- 关于CMTS设备的一些备忘
博主工作内容包括cable modem,对CM的工作方式有一些了解,但是对CMTS头端怎么带动一个用户小区长久以来一直是一头雾水.今天找了些资料,对这块有了一些了解,并把自己的理解总结下来. 比如我家 ...
- C# 中异常抛出捕获机制--throw / try,catch,finally
try { messagebox.show("true"); } catch { messagebox.show("false"); } finally { m ...
- 整型,布尔值,字符串详解,for语句 练习
2019 年 7 月 8 日 1.将今天的课上的代码敲一遍,然后整理笔记 已完成 2.有变量name = "aleX leNb" 完成如下操作: 移除 name 变量对应的值两边的 ...
