array(2) { ["docs"]=> array(10) { [0]=> array(10) { ["id"]=> string(3) "428" ["text"]=> string(77) "Visual Studio 2017 单独启动MSDN帮助(Microsoft Help Viewer)的方法" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(8) "DonetRen" ["tagsname"]=> string(55) "Visual Studio 2017|MSDN帮助|C#程序|.NET|Help Viewer" ["tagsid"]=> string(23) "[401,402,403,"300",404]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511400964" ["_id"]=> string(3) "428" } [1]=> array(10) { ["id"]=> string(3) "427" ["text"]=> string(42) "npm -v;报错 cannot find module "wrapp"" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(4) "zzty" ["tagsname"]=> string(50) "node.js|npm|cannot find module "wrapp“|node" ["tagsid"]=> string(19) "[398,"239",399,400]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511400760" ["_id"]=> string(3) "427" } [2]=> array(10) { ["id"]=> string(3) "426" ["text"]=> string(54) "说说css中pt、px、em、rem都扮演了什么角色" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(12) "zhengqiaoyin" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511400640" ["_id"]=> string(3) "426" } [3]=> array(10) { ["id"]=> string(3) "425" ["text"]=> string(83) "深入学习JS执行--创建执行上下文(变量对象,作用域链,this)" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(7) "Ry-yuan" ["tagsname"]=> string(33) "Javascript|Javascript执行过程" ["tagsid"]=> string(13) "["169","191"]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511399901" ["_id"]=> string(3) "425" } [4]=> array(10) { ["id"]=> string(3) "424" ["text"]=> string(30) "C# 排序技术研究与对比" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(9) "vveiliang" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(8) ".Net Dev" ["catesid"]=> string(5) "[199]" ["createtime"]=> string(10) "1511399150" ["_id"]=> string(3) "424" } [5]=> array(10) { ["id"]=> string(3) "423" ["text"]=> string(72) "【算法】小白的算法笔记:快速排序算法的编码和优化" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(9) "penghuwan" ["tagsname"]=> string(6) "算法" ["tagsid"]=> string(7) "["344"]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511398109" ["_id"]=> string(3) "423" } [6]=> array(10) { ["id"]=> string(3) "422" ["text"]=> string(64) "JavaScript数据可视化编程学习(二)Flotr2,雷达图" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(7) "chengxs" ["tagsname"]=> string(28) "数据可视化|前端学习" ["tagsid"]=> string(9) "[396,397]" ["catesname"]=> string(18) "前端基本知识" ["catesid"]=> string(5) "[198]" ["createtime"]=> string(10) "1511397800" ["_id"]=> string(3) "422" } [7]=> array(10) { ["id"]=> string(3) "421" ["text"]=> string(36) "C#表达式目录树(Expression)" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(4) "wwym" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(4) ".NET" ["catesid"]=> string(7) "["119"]" ["createtime"]=> string(10) "1511397474" ["_id"]=> string(3) "421" } [8]=> array(10) { ["id"]=> string(3) "420" ["text"]=> string(47) "数据结构 队列_队列实例:事件处理" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(7) "idreamo" ["tagsname"]=> string(40) "C语言|数据结构|队列|事件处理" ["tagsid"]=> string(23) "["246","247","248",395]" ["catesname"]=> string(12) "数据结构" ["catesid"]=> string(7) "["133"]" ["createtime"]=> string(10) "1511397279" ["_id"]=> string(3) "420" } [9]=> array(10) { ["id"]=> string(3) "419" ["text"]=> string(47) "久等了,博客园官方Android客户端发布" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(3) "cmt" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511396549" ["_id"]=> string(3) "419" } } ["count"]=> int(200) } 222 【spring boot】SpringBoot初学(2.2)– SpEL表达式读取properties属性到Java对象 - 爱码网

前言

  github: https://github.com/vergilyn/SpringBootDemo

  代码位置:(注意测试方法在,test下的SpelValueApplicationTest.class

    【spring boot】SpringBoot初学(2.2)– SpEL表达式读取properties属性到Java对象

一、什么是SpEL

  SpEL:spring表达式语言,Spring Expression Language。从spring3开始引入。

  可以通过xml或注解的施行映射properties中的属性到JavaBean,并通过Spring注入。

二、Spring boot中常见的应用

@Value("${base.name}")
private String baseName;

@Value("#{'string'}") // 或 @Value('#{"string"}')
public String spelString;

  (个人理解) 以$开头的只是普通模式,而以#开头的才是SpEL。

  针对这两种,它们默认值的写法也是不一样的。

${ property : default_value }
#{ obj.property ?: default_value }

三、以$取值

## value-base.properties
base.name=vergil
base.song=Safe&Sound
base.nest.song=base.song
package com.vergilyn.demo.spring.value.property;

import java.util.Calendar;
import java.util.Date;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;

@PropertySource("classpath:config/value/value-base.properties")
@Component("base")
public class BaseProperty {
	@Value("${base.name}")
	private String baseName;
	@Value("${base.song}")
	private String baseSong;
	/* 嵌套(内往外)
	 * 解析:先取内部${base.nest.song}=base.song -> ${base.song} = Safe&Sound
	 */
	@Value(value = "${${base.nest.song}}")
	private String nestSong;

	@Override
	public String toString() {
		return this.getClass().getSimpleName() +":{baseName: "+this.baseName+", baseSong: "+this.baseSong+"}";
	}

	public String getBaseName() {
		return baseName;
	}
	public void setBaseName(String baseName) {
		this.baseName = baseName;
	}
	public String getBaseSong() {
		return baseSong;
	}
	public void setBaseSong(String baseSong) {
		this.baseSong = baseSong;
	}

	public String getNestSong() {
		return nestSong;
	}

	public void setNestSong(String nestSong) {
		this.nestSong = nestSong;
	}

	public Date nowDate(){
		return Calendar.getInstance().getTime();
	}
}

结果:

    BaseProperty: {"baseName":"vergil","baseSong":"Safe&Sound","nestSong":"Safe&Sound"}

四、以#取值 一般形式

## value-spel.properties
spel.name=dante
spel.mix=baseSong
package com.vergilyn.demo.spring.value.property;

import java.util.Date;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;

@PropertySource("classpath:config/value/value-spel.properties")
@Component
public class SpelProperty {

	@Value("${spel.name}")  //注意这里是 $
	private String spelName;
	/* base:指BaseProperty.class(默认为baseProperty),因为定义了@Component("base")
	 * baseSong:并不是*.properties中的key,而是此key对应的class变量
	 */
	@Value("#{base.baseSong}")
	private String spelSong;
	/* // @Value("${ '#{base.baseSong}' }") //这个不支持。因为#开头的才是spel。
	 * 解析:由内往外,${spel.mix} = baseSong。然后在spel表达式中,('')表示定义字符串。
	 * 所以 #{'baseSong'} = baseSong
	 */
	@Value("#{ '${spel.mix}' }")
	private String mixSong;
	@Value("#{base. ${spel.mix} }") //组合,特别.后面跟的是对象属性。所以要是class中的属性,而不是properties中的key
	private String mixSong2;

	public String getMixSong2() {
		return mixSong2;
	}
	public void setMixSong2(String mixSong2) {
		this.mixSong2 = mixSong2;
	}
	public String getSpelName() {
		return spelName;
	}
	public void setSpelName(String spelName) {
		this.spelName = spelName;
	}
	public String getSpelSong() {
		return spelSong;
	}
	public void setSpelSong(String spelSong) {
		this.spelSong = spelSong;
	}

	public String getMixSong() {
		return mixSong;
	}
	public void setMixSong(String mixSong) {
		this.mixSong = mixSong;
	}
}

结果:

  SpelProperty: {"mixSong":"baseSong","mixSong2":"Safe&Sound","spelName":"dante","spelSong":"Safe&Sound"}

四、以#取值 各种复杂形式

package com.vergilyn.demo.spring.value.property;

import java.util.Date;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component
public class SpelBasisProperty {

	@Value("#{124}")
	public int spelInt;
	@Value("#{124.24}")
	public float spelFloat;
	@Value("#{1e4}")
	public double spelSpec;
	@Value("#{true}")
	public boolean spelBoolean = false;
	@Value("#{'string'}") // 或 @Value('#{"string"}')
	public String spelString;
	/* 调用方法。
	 * 在SpEL中避免抛出空指针异常(NullPointException)的方法是使用null-safe存取器:
	 * ?. 运算符代替点(.) #{object?.method()},如果object=null,则不会调用method()
	 */
	@Value("#{base.getNestSong()}")
	public String spelNestSong;
	@Value("#{base.nowDate()}")	//返回值可以是任何类型
	public Date spelNowDate;
	@Value("#{null?.toString()}")	//当?.左边为null时,不再执行右边的方法。(避免NPE)
	public String spelNull;

	/**
	 * 在SpEL中,使用T()运算符会调用类作用域的方法和常量。
	 */
	@Value("#{T(java.lang.Math).PI}")
	public double T_PI;
	@Value("#{T(java.lang.Math).random()}")
	public double T_andom;

	/**
	 * SpEL运算>>>>
	 *  四则运算:+ - * /
	 *  比较:eq(==),lt(<),le(<=),gt(>),ge(>=)。
	 *  逻辑表达式:and,or,not或!。
	 *  三元表达式:
	 *  	i. #{base.name == 'vergilyn' ? true : false}
	 *  	ii. #{base.name == 'vergilyn' ? base.name : 'dante'}
	 *  	  spel可以简化为:#{base.name  ?: 'dante'} 当base.name !=null则取base.name,否则取'dante'。
	 *  	(?:)通常被称为elvis运算符。
	 *  正则:#{base.song matches '[a-zA-Z0-9._%+_][email protected][a-zA-Z0-9.-]+\\.com'} 。 (不光有matches,还有很多别的,可详细baidu/google)
	 */
	@Value("#{100 / 20}")	//四则运算: + - * /
	public int spelArithmetic;
}

结果:

  SpelBasisProperty: {"T_PI":3.141592653589793,"T_andom":0.49286684542729553,"spelArithmetic":5,"spelBoolean":true,"spelFloat":124.24,"spelInt":124,"spelNestSong":"Safe&Sound","spelNowDate":1489169611736,"spelSpec":10000.0,"spelString":"string"}

相关文章: