Spring Boot 教程

@ConditionalOnExpression 注解

在 Spring Boot 中,@ConditionalOnExpression 条件注解允许我们将条件指定为有效的 SpEL 表达式,根据 SpEL 表达式的计算结果来判断条件是否匹配。

什么是 SpEL?

SpEL 的全称为 Spring Expression Language(即 Spring 表达式预研)是一种强大的表达式语言。在 Spring 产品组合中,它是表达式计算的基础。它支持在运行时查询和操作对象图,它可以与基于 XML 和基于注解的 Spring 配置还有 bean 定义一起使用。由于它能够在运行时动态分配值,因此可以为我们节省大量 Java 代码。

SpEL 支持标准数学运算符,关系运算符,逻辑运算符,条件运算符,集合和正则表达式等。它可用于将 bean 或 bean 属性注入另一个bean,还支持 bean 的方法调用。以下是 SpEL 的一些基本功能和操作符:

  • 文字表达式可用于 SpEL 表达式。例如,“Hello SpEL” 是一个字符串文字。如果此文字用作 SpEL 表达式,则结果值也将为 “Hello SpEL”。

  • SpEL 表达式支持方法调用。例如,可以从 String 文字中调用 concat 方法。

  • SpEL 表达式支持数学运算符。所有基本运算符,如加法(+),减法( - ),乘法(*),除法(/),模数(%),指数幂(^)等,都可以在 SpEL 表达式中使用。

  • 关系运算符等于(==),不等于(!=),小于(<),小于或等于(<=),大于(>),大于或等于(> =)在 SpEL 表达式中同样支持。要在基于XML的配置中使用关系运算符,应使用文本等效项eq,ne,lt,le,gt,ge。

  • 支持逻辑运算符,与(&&)或(||)非(!),也可以使用等价文本。

  • 三元运算符用于在 SpEL 表达式中执行 if-then-else 条件逻辑。当我们需要根据某些条件注入值时,它很有用。

  • Elvis 算子是三元运算符的缩短形式。三元运算符的一个常见用途是对变量进行空值检查,然后返回变量值或默认值,Elvis操作很方便。

  • SpEL 表达式支持使用正则表达式,我们需要使用 matches 运算符来检查字符串是否与给定的正则表达式匹配。

示例

我们在 application.properties 文件中添加一些配置信息,然后在 @Configuration 类上面使用 @ConditionalOnExpression 注解通过 SpEL 表达式来获取这些配置信息,然后进行判断。如果符合我们预期的值,则匹配成功,实例化它。

(1)application.properties 配置文件

hxstrive.type=server
hxstrive.user.enable=true
hxstrive.order.size=10

(2)创建两个服务,分别为 UserService(用户服务) 和 OrderService(订单服务),如下:

a、UserService.java

package com.huangx.springboot.autoconfig.service;

public class UserService {
    // 什么也不做
}

b、OrderService.java

package com.huangx.springboot.autoconfig.service;

public class OrderService {
    // 什么也不做
}

(3)创建我们的 @Configuration 配置类,如下:

a、UserConfig.java 配置用户服务

package com.huangx.springboot.autoconfig.config;

import com.huangx.springboot.autoconfig.service.UserService;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
// 要求 hxstrive.type 必须等于 “server”
// 要求 hxstrive.user.enable 必须等于 true
// 它才能去初始化 UserService 服务
@ConditionalOnExpression("'${hxstrive.type}'.equals('server') && (${hxstrive.user.enable})")
public class UserConfig {

    @Bean
    public UserService userService() {
        System.out.println("UserService -> userService()");
        return new UserService();
    }

}

b、OrderConfig.java 配置订单服务

package com.huangx.springboot.autoconfig.config;

import com.huangx.springboot.autoconfig.service.OrderService;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
// 要求 hxstrive.type 必须等于 “server”
// 要求 hxstrive.order.size 必须大于 0
// 它才能去初始化 OrderService 服务
@ConditionalOnExpression("'${hxstrive.type}'.equals('server')" +
        " && (${hxstrive.order.size:0} > 0)")
public class OrderConfig {

    @Bean
    public OrderService orderService() {
        System.out.println("OrderConfig -> orderService()");
        return new OrderService();
    }

}

(4)客户端代码,如下:

package com.huangx.springboot.autoconfig;

import com.huangx.springboot.autoconfig.service.OrderService;
import com.huangx.springboot.autoconfig.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@SpringBootApplication
public class Demo4Application {

    @Autowired
    private ApplicationContext applicationContext;

    public static void main(String[] args) {
        SpringApplication.run(Demo4Application.class, args);
    }

    @GetMapping("/")
    public String index() {
        // 尝试获取服务
        UserService userService = null;
        try {
            userService = applicationContext.getBean(UserService.class);
        } catch (Exception e) {
            System.err.println(e.getMessage());
        }

        OrderService orderService = null;
        try {
            orderService = applicationContext.getBean(OrderService.class);
        } catch (Exception e) {
            System.err.println(e.getMessage());
        }

        return "userService=" + userService + "<br/>" +
                "orderService=" + orderService;
    }

}

启动 Spring Boot 程序,然后在浏览器中访问 http://localhost:8080 地址,运行效果如下图:

如果你将 OrderConfig 上面的 @ConditionalOnExpression 的 hxstrive.order.size 条件进行调整,要求 hxstrive.order.size 的值必须大于 100,如下:

@Configuration
@ConditionalOnExpression("'${hxstrive.type}'.equals('server')" +
        " && (${hxstrive.order.size:0} > 100)")
public class OrderConfig {

    @Bean
    public OrderService orderService() {
        System.out.println("OrderConfig -> orderService()");
        return new OrderService();
    }

}

运行效果如下图:

说说我的看法
全部评论(
没有评论
关于
本网站专注于 Java、数据库(MySQL、Oracle)、Linux、软件架构及大数据等多领域技术知识分享。涵盖丰富的原创与精选技术文章,助力技术传播与交流。无论是技术新手渴望入门,还是资深开发者寻求进阶,这里都能为您提供深度见解与实用经验,让复杂编码变得轻松易懂,携手共赴技术提升新高度。如有侵权,请来信告知:hxstrive@outlook.com
公众号