【spring boot】SpringBoot初學(2.2)– SpEL表達式讀取properties屬性到Java對象


前言

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

  代碼位置:(注意測試方法在,test下的SpelValueApplicationTest.class

    image

一、什么是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._%+_]+@[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"}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM