首页 > 其他分享 >springboot SpEL关于@ConditionalOnExpression注解,在使用spel表达式引用配置属性bean导致提前初始化,无绑定数据的问题及相应的解决方法。

springboot SpEL关于@ConditionalOnExpression注解,在使用spel表达式引用配置属性bean导致提前初始化,无绑定数据的问题及相应的解决方法。

时间:2023-02-10 16:15:08浏览次数:56  
标签:ConditionalOnExpression springboot bean springframework spel 注解 属性

springboot 关于@ConditionalOnExpression注解,在使用spel表达式引用配置属性bean导致提前初始化,无绑定数据的问题及相应的解决方法。

SpringBoot版本

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.7</version>
    </parent>

原始需求

一开始我的需求就是想通过yml配置文件里的数组结构的值,从而判断指定bean是否进行注册到IOC容器中。
不过后来通过观察Environment bean的注入结果,发现里面的属性都被扁平化了。
例如:

students:
  groups:
    - xiaoming
    - xiaowang

在Environment里的体现为:
students.groups[0]=xiaoming
students.groups[1]=xiaowang

后来想通过@ConfigurationProperties配置bean,将yml文件的数组结构映射到下边的配置bean。

public class Student{
   private List<Student> groups;
// ...get  ...set
}

最后,值是映射到groups里了,到这一步是ok的。

然后通过@ConditionalOnExpression注解使用spel,结果导致 配置bean提前初始化,状态不完整,所以groups属性等于null。
通过看官方springboot文档,对其解释引用的bean会被提前初始化,导致状态不完整

最后也是只能作罢。

最后只能自己实现了。没招了。

问题原因

org.springframework.boot.autoconfigure.condition.ConditionalOnExpression注解的注释说明了,在spel引用的bean会提前初始化,导致bean的状态不完整导致的。

@ConditionalOnExpression注解虽然使用可以使用spel引用bean,但是我觉的还是适用到那些标记Bean或通过配置值进行判断的情况。
如果在#{ @xxxBean.property }的话,那这时候xxxBean下的属性可能会为null,也就是配置文件的属性值没绑定到bean中。

关于@ConditionalOnExpression注解的讨论

Github 注释方法时属性值未正确加载@ConditionalOnExpression

解决方法

第一种,直接使用@ConditionalOnExpression注解的spel表达式不引用配置bean了,通过获取配置文件的属性直接进行条件的限定。

// 以下表达式就是当 值 在数组里包含,则返回true,否则返回false。经测试,可行。
@ConditionalOnExpression(value = "#{ T(org.springframework.boot.context.properties.bind.Binder).get(environment).bind('yml配置里的数组结构的完整Key', T(org.springframework.boot.context.properties.bind.Bindable).listOf(T(String))).get().contains('你想包含的数组值') }")

第二种就是自己将以上的逻辑包装为注解。

实现逻辑类需要继承org.springframework.boot.autoconfigure.condition.SpringBootCondition类,方便实现,里面加入了共用的逻辑,你只需要依葫芦画瓢就行了。
然后在你的自定义注解上加上org.springframework.context.annotation.Conditional注解,value=你自己实现的条件类,这样就可以了。

最后使用,只需要放在你需要进行条件限定的类,并加上属性和值的指定,基本就ok了。

参阅资源

SpEL expressions-types
SpEL Expression Conditions
stackoverflow conditionalonexpression

标签:ConditionalOnExpression,springboot,bean,springframework,spel,注解,属性
From: https://www.cnblogs.com/XingXiaoMeng/p/17109291.html

相关文章

  • SpringBoot解决跨域问题
    遇到前端跨域访问问题,类似于这样的:在Springboot项目里加上这个配置文件CorsConfig.java,重启之后即可实现跨域访问,前端无需再配置跨域。importorg.springframework.......
  • SpringBoot Response统一返回封装,全局异常处理
    背景经常写代码,很多公司的Restful都是code,msg,data这种封装{"code":0,"msg":null,"data":null}后端代码:@GetMapping("hello")publicResultlist......
  • springboot将http改造成https
    生成命令:keytool-genkey-aliastestalias-storetypePKCS12-keyalgRSA-keysize2048-keystorekeystore.p12-validity365关键字解释:alias  密钥别名store......
  • SpringBoot 项目实战 | 瑞吉外卖 Day05
    该系列将记录一份完整的实战项目的完成过程,该篇属于第五天案例来自B站黑马程序员Java项目实战《瑞吉外卖》,请结合课程资料阅读以下内容该篇我们将完成以下内容:新增套餐......
  • springboot3 security 从始至终--03 UserDetails
    一、定义/***Providescoreuserinformation.**<p>*ImplementationsarenotuseddirectlybySpringSecurityforsecuritypurposes.They*simplysto......
  • springboot集成swagger
    pom<?xmlversion="1.0"encoding="UTF-8"?><projectxmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"x......
  • shiro、springboot、vue、elementUI CDN模式前后端分离的权限管理demo 附源码
    源码下载地址https://github.com/Aizhuxueliang/springboot_shiro.git前提你电脑的安装好这些工具:jdk8、idea、maven、git、mysql;shiro的主要概念Shiro是一个强大的......
  • springboot生成图形验证码
    pom.xml<dependency><groupId>com.github.penggle</groupId><artifactId>kaptcha</artifactId><version>2.3.2</versio......
  • springboot开发日记(9)——YAML配置文件
    YAML——适合用来做以数据为中心的配置文件基本语法使用缩进表示层级关系。缩进时不允许使用Tab键,只允许使用空格。(实际使用idea开发中,Tab也有效)缩进的空格数不重......
  • Spring43 - Bean Validation注解
    BeanValidation注解实现使用BeanValidation校验方式,就是如何将BeanValidation需要使用的javax.validation.ValidatorFactory和javax.validation.Validator注入到容器......