【SpringBoot 基础系列】@Value 之字面量及 SpEL 知识点介绍篇
承接上一篇博文【SpringBoot 基础系列】@Value 中哪些你不知道的知识点 中说起到但没有细说的知识点,这一篇博文未来看一下@Value
除了绑定配置文件中的属性配置以外,另外支持的两种姿式java
<!-- more -->git
本项目借助SpringBoot 2.2.1.RELEASE
+ maven 3.5.3
+ IDEA
进行开发github
开一个 web 服务用于测试web
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> </dependencies>
上一篇的博文知道经过${}
能够获取配置文件中对应的配置值,接下来咱们看一下另外两种常见的姿式redis
字面量的使用比较简单,直接在@Value
注解中写常量spring
一个 demo 以下app
@Value("1 + 2") private String common;
上面这种初始化以后,common 的值会是 1 + 2
;若是只是这种用法,这个东西就有些鸡肋了,我直接赋值不香嘛,为啥还有这样画蛇添足呢?dom
固然现实中(至少我有限的代码接触中),纯上面这种写法的很少,更常见的是下面这种maven
@Value("demo_${auth.jwt.token}") private String prefixConf;
字面量 + 配置联合使用,如咱们的配置文件值为spring-boot
auth: jwt: token: TOKEN.123
上面的 prefixConf 的取值,实际为 demo_TOKEN.123
@Value 另一个很强的使用姿式是支持 SpEL 表达式,至于 SpEL 是什么鬼,推荐查看【SpringBoot 基础系列】SpEL 语法扫盲与查询手册
使用姿式是 #{}
,表示这个大括弧里面的走 SpEL 表达式,以下
/** * 字符串 */ @Value("#{'abcd'}") private String spelStr; /** * 基本计算 */ @Value("#{1 + 2}") private String spelVal3; /** * 列表 */ @Value("#{{1, 2, 3}}") private List<Integer> spelList; /** * map */ @Value("#{{a: '123', b: 'cde'}}") private Map spelMap;
上面是几个基本的 case 了,字面量,表达式,列表/Map 等,SpEL 的基本使用姿式与扫盲博文中的没有什么区别,无外乎就是在外层多了一个${}
固然若是仅仅只是介绍上面几个的话,就有点单调了,SpEL 一个比较强大的就是能够访问 bean 的属性/方法,这就给了咱们不少的想像空间了
在上面这个配置类com.git.hui.boot.properties.value.config.SpelProperties
中添加一个静态方法
public static String uuid() { return "spel_" + UUID.randomUUID().toString().replaceAll("_", "."); }
而后咱们尝试调用它
/** * 调用静态方法 */ @Value("#{T(com.git.hui.boot.properties.value.config.SpelProperties).uuid()}") private String spelStaticMethod;
这样spelStaticMethod
就会是一个 "spel_"
开头的随机字符串了
请注意:若是在你的实际生产项目中,写出这样的代码,那多半意味着离找下家不远了
接下来借助 SpEL 与配置绑定的嵌套使用,来稍微调整下上面的实现(实际上下面这种用法也不常见,虽然没问题,但这种代码就属于写时一时爽,维护火葬场了 🙄)
/** * 调用静态方法 */ @Value("#{T(com.git.hui.boot.properties.value.config.SpelProperties).uuid('${auth.jwt.token}_')}") private String spelStaticMethod; public static String uuid(String prefix) { return prefix + UUID.randomUUID().toString().replaceAll("_", "."); }
关于嵌套使用,下面再给出一个基础的使用姿式,供打开思路用
/** * 嵌套使用,从配置中获取值,而后执行SpEL语句 */ @Value("#{'${auth.jwt.token}'.substring(2)}") private String spelLen;
最后再来一个访问 bean 的方法的 case
定义一个 Service
@Service public class RandomService { private AtomicInteger cnt = new AtomicInteger(1); public String randUid() { return cnt.getAndAdd(1) + "_" + UUID.randomUUID().toString(); } }
一个使用的姿式以下
/** * bean 方法访问 */ @Value("#{randomService.randUid()}") private String spelBeanMethod;
最后给出一个注入的结果输出,查看下有没有什么偏离预期的场景
@RestController @SpringBootApplication public class Application { @Autowired private SpelProperties spelProperties; @GetMapping("spel") public SpelProperties showSpel() { return spelProperties; } public static void main(String[] args) { SpringApplication.run(Application.class); } }
本篇博文主要介绍了@Value
除了绑定配置文件中的配置以外,另外两种常见的 case
#{}
里面借助 SpEL 的强大功能,彻底能够发挥咱们的脑洞,让@Value
修饰的属性初始化再也不局限于简单的配置文件,好比从 db,redis,http 获取彻底是可行的嘛,无非就是一个表达式而已
固然这里还存在一个待解决的问题,就是值刷新的支持,已知@Value
只在 bean 初始化时执行一次,后续即使配置变动了,亦不会从新更改这个值,这种设计有好有坏,好处很明显,配置的不变性能够省去不少问题;缺点就是不灵活
那么如何让@Value
的配置能够动态刷新呢?
咱么下篇博文见,我是一灰灰,欢迎关注长草的公众号一灰灰blog
配置系列博文
尽信书则不如,以上内容,纯属一家之言,因我的能力有限,不免有疏漏和错误之处,如发现 bug 或者有更好的建议,欢迎批评指正,不吝感激
下面一灰灰的我的博客,记录全部学习和工做中的博文,欢迎你们前去逛逛