linux condition用法,一文了解@Conditional注解说明和使用

本文详细介绍了Spring框架中的@Conditional注解,该注解用于在特定条件下注册bean。通过实现Condition接口并自定义匹配逻辑,可以在不同系统环境下注册不同的bean。示例中展示了如何根据操作系统环境(Linux、Windows、MacOSX)注册不同的类。此外,还讨论了@Conditional与@Profile的区别,@Conditional提供了更灵活的条件检查能力。
摘要由CSDN通过智能技术生成

​ @Conditional:Spring4.0 介绍了一个新的注解@Conditional,它的逻辑语义可以作为"If…then…else…"来对bean的注册起作用。

@Contidional 介绍

​ Conditional 是由 SpringFramework 提供的一个注解,位于 org.springframework.context.annotation 包内,定义如下。

package org.springframework.context.annotation;

import java.lang.annotation.ElementType;

import java.lang.annotation.Retention;

import java.lang.annotation.RetentionPolicy;

import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)

@Target({ElementType.TYPE, ElementType.METHOD})

public @interface Conditional {

Class extends Condition>[] value();

}

​ SpringBoot 模块大量的使用@Conditional 注释,我们可以将Spring的@Conditional注解用于以下场景:

可以作为类级别的注解直接或者间接的与@Component相关联,包括@Configuration类;

可以作为元注解,用于自动编写构造性注解;

作为方法级别的注解,作用在任何@Bean方法上。

Condition 接口

​ 我们需要一个类实现Spring提供的Condition接口,它会匹配@Conditional所符合的方法,然后我们可以使用我们在@Conditional注解中定义的类来检查。

public interface Condition {

boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata);

}

Spring @Conditional注解实例

作用在方法上

​ 先来看一个简单一些的示例,我们假设有三个角色老师Teacher、学生Student和父母Parent,三种环境Linux、Windows和MacOSX,如果是Linux环境,就注册Teacher,如果是Windows环境就注册Parent,如果是Mac 环境就注册Student。代码示例如下:

首先创建Teacher和Student对象,没有任何的属性和方法,只是一个空类

//如果当前工程运行在Windows系统下,就注册Student

public class Student {}

//如果当前工程运行在Linux系统下,就注册Teacher

public class Teacher {}

// 如果是Mac OSX 系统,就注册Parent

public class Parent {}

创建一个LinuxCondition和一个WindowsCondition,LinuxCondition能够匹配Linux环境,WindowsCondition能够匹配Windows环境,MacOSX 系统匹配mac环境。

import org.springframework.context.annotation.Condition;

import org.springframework.context.annotation.ConditionContext;

import org.springframework.core.type.AnnotatedTypeMetadata;

import org.springframework.stereotype.Component;

public class LinuxCondition implements Condition {

public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {

// 获取系统环境的属性

String systemName = context.getEnvironment().getProperty("os.name");

if(systemName.contains("Linux")){

return true;

}

return false;

}

}

import org.springframework.context.annotation.Condition;

import org.springframework.context.annotation.ConditionContext;

import org.springframework.core.type.AnnotatedTypeMetadata;

//自定义一个判断条件

public class WindowsCondition implements Condition {

/*

* ConditionContext context: spring容器上下文环境

* AnnotatedTypeMetadata metadata :@Conditional修饰类型信息

*/

public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {

String systemName = context.getEnvironment().getProperty("os.name");

if(systemName.contains("Windows")){

return true;

}

return false;

}

}

import org.springframework.context.annotation.Condition;

import org.springframework.context.annotation.ConditionContext;

import org.springframework.core.type.AnnotatedTypeMetadata;

public class OsxCondition implements Condition {

@Override

public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {

String property = context.getEnvironment().getProperty("os.name");

if(property.equals("Mac OS X")){

return true;

}

return false;

}

}

下面来新建匹配注册环境,如果系统是Linux环境,就注册Teacher,如果系统是Windows,就注册Parent,如果是Mac 系统,就注册Student

import com.spring.condition.beans.Parent;

import com.spring.condition.beans.Student;

import com.spring.condition.beans.Teacher;

import com.spring.condition.util.LinuxCondition;

import com.spring.condition.util.OsxCondition;

import com.spring.condition.util.WindowsCondition;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Conditional;

import org.springframework.context.annotation.Configuration;

@Configuration

public class AppConfig {

@Conditional(OsxCondition.class)

@Bean

public Student student(){

return new Student();

}

@Conditional(LinuxCondition.class)

@Bean

public Teacher teacher(){

return new Teacher();

}

@Conditional(WindowsCondition.class)

@Bean

public Parent parent(){

return new Parent();

}

}

新建测试类进行测试

import com.spring.condition.config.AppConfig;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class ConditionTest {

public static void main(String[] args) {

AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);

String[] names = context.getBeanDefinitionNames();

for(String name : names){

System.out.println("name = " + name);

}

}

}

由输出可以看出,name = student 被输出到控制台,也就是说,我当前所用的系统环境是MacOSX环境,所以注册的是OSXCondition,也就是student的bean。

手动设置系统环境

也可以进行手动修改vm.options,把当前的系统环境变为Linux 或者Windows,以Idea为例:

40b5671bdeacb563eef1a36252cabe5a.png

在Edit Configurations中找到vm.options 选项,把系统环境改为 Linux,如下:

e7aa9f9946c6bda67682164a7ab65130.png

然后重新启动测试,发现Teacher 被注入进来了,修改当前环境为Windows,观察Parent也被注入进来并输出了。

作用在类上

​ @Conditional 注解可以作用在类上,表示此类下面所有的bean满足条件后都可以进行注入,通常与@Configuration注解一起使用。

新建一个AppClassConfig,在类上标注@Conditional()注解,并配置相关bean,如下:

@Configuration

@Conditional(value = OsxCondition.class)

// 修改config,如果满足OsxCondition环境的话,就把student,parent,teacher都注册进来

public class AppClassConfig {

@Bean

public Student student(){

return new Student();

}

@Bean

public Teacher teacher(){

return new Teacher();

}

@Bean

public Parent parent(){

return new Parent();

}

}

上文表示如果是OsxCondition.class 的话,就注册student、teacher、parent

测试类不用修改,直接用原测试类进行测试,发现student、 teacher、 parent 都被注册进来了

多个条件类

​ 因为@Conditional注解的value 方法默认传递一个数组,所以可以接受多个condition,为了测试如下情况,

新建一个 TestCondition类,如下:

// 单纯为了测试

public class TestCondition implements Condition {

@Override

public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {

// 返回false,表示不匹配

return false;

}

}

修改一下AppClassConfig

@Configuration

@Conditional(value = {OsxCondition.class,TestCondition.class})

// 修改config,如果满足OsxCondition环境的话,就把student,parent,teacher都注册进来

public class AppClassConfig {

@Bean

public Student student(){

return new Student();

}

@Bean

public Teacher teacher(){

return new Teacher();

}

@Bean

public Parent parent(){

return new Parent();

}

}

也就是给@Conditional 多加了一个参数 TestCondition.class

启动之前的测试类,发现上述的bean都没有注入,也就是说,只有在满足OsxCondition.class 和 TestCondition.class 都为true的情况下,才会注入对应的bean,修改TestCondition.class的matches方法的返回值为true,重新观察返回结果,发现上述bean都被注入了。

@Conditional 与@Profile 的对比

​ @Spring3.0 也有一些和@Conditional 相似的注解,它们是Spring SPEL 表达式和Spring Profiles 注解 Spring4.0的@Conditional 注解要比@Profile 注解更加高级。@Profile 注解用来加载应用程序的环境。@Profile注解仅限于根据预定义属性编写条件检查。 @Conditional注释则没有此限制。

​ Spring中的@Profile 和 @Conditional 注解用来检查"If…then…else"的语义。然而,Spring4 @Conditional是@Profile 注解的更通用法。

Spring 3中的 @Profiles仅用于编写基于Environment变量的条件检查。 配置文件可用于基于环境加载应用程序配置。

Spring 4 @Conditional注解允许开发人员为条件检查定义用户定义的策略。 @Conditional可用于条件bean注册。

文章参考:

https://blog.csdn.net/xcy1193068639/article/details/81491071

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值