zoukankan      html  css  js  c++  java
  • 【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"}

  • 相关阅读:
    上周热点回顾(7.29-8.4)团队
    云计算之路:AWS, Azure, Aliyun, UCloud提供的Windows操作系统团队
    上周热点回顾(7.22-7.28)团队
    我的MYSQL学习心得(推荐)
    深度学习笔记之使用Faster-Rcnn进行目标检测 (实践篇)
    深度学习笔记之使用Faster-Rcnn进行目标检测 (原理篇)
    深度学习笔记之基于R-CNN的物体检测
    深度学习笔记之目标检测算法系列(包括RCNN、Fast RCNN、Faster RCNN和SSD)
    深度学习笔记之神经网络、激活函数、目标函数和深度的初步认识
    深度学习笔记之CNN(卷积神经网络)基础
  • 原文地址:https://www.cnblogs.com/VergiLyn/p/6533821.html
Copyright © 2011-2022 走看看