Spring SpEL系列一 基础用法

来源:互联网 发布:asp.net 微信商城源码 编辑:程序博客网 时间:2024/05/17 04:28

1. 概述

1.1. 概念

在Spring @Value 属性注入使用总结二中提到使用@Value注入属性值。为了更深入的使用的@Value,我们引入 SpEL。通过Spring的表达式注入更复杂的内容

2. 辅助类

以下演示SpEL的用法需要用到的辅助类:
Inventor:测试类

public class Inventor {    private String name;    private String nationality;    private String[] inventions;    private Date birthdate;    private PlaceOfBirth placeOfBirth;    private List<PlaceOfBirth> placeOfBirthList;    private Map<String,Integer> map = new HashMap<String, Integer>();    public Inventor(String name, String nationality) {        GregorianCalendar c= new GregorianCalendar();        this.name = name;        this.nationality = nationality;        this.birthdate = c.getTime();    }    public Inventor(String name, Date birthdate, String nationality) {        this.name = name;        this.nationality = nationality;        this.birthdate = birthdate;    }    /**     * 传入name是否和对象成员变量name相同     * @param name     * @return     */    public boolean nameIsSame(String name){        return this.name.equals(name);    }    // set/get方法略}

PlaceOfBirth:Inventor里的成员类

public class PlaceOfBirth {    private String city;    private String country;    public PlaceOfBirth(String city) {        this.city = city;    }    public PlaceOfBirth(String city, String country) {        this(city);        this.country = country;    }}

启动类,并定义Inventor的值

@SpringBootApplication@Configurablepublic class SpELAnnotationApplication {    public static void main(String[] args) {        SpringApplication.run(SpELAnnotationApplication.class, args);    }    // 初始化测试所需要的对象    @Bean("inventor")    public Inventor getInventor(){        Inventor invertor = new Inventor("name",new Date(),"nationality");        // 设置placeOfBirth        invertor.setPlaceOfBirth(new PlaceOfBirth("city", "country"));        // 设置string数组        invertor.setInventions(new String[]{"inventions_1","inventions_2","inventions_3","inventions_4"});        // 设置PlaceOfBirth的List        List<PlaceOfBirth> placeOfBirthList = new ArrayList<PlaceOfBirth>();        placeOfBirthList.add(new PlaceOfBirth("city_list_1", "country_list_1"));        placeOfBirthList.add(new PlaceOfBirth("city_list_2", "country_list_2"));        placeOfBirthList.add(new PlaceOfBirth("city_list_3", "country_list_3"));        invertor.setPlaceOfBirthList(placeOfBirthList);        // 设置map值         Map<String, Integer> map = new HashMap<String, Integer>();        map.put("mapKey_1", 1);        map.put("mapKey_2", 2);        map.put("mapKey_3", 3);        invertor.setMap(map);        return invertor;    }}

3. Spring EL 常用语法

这里只使用@Value显示Sp EL的用法,Java代码和XML的用法类似,这样暂时不演示。
Spring EL各种语法,详细如下。

3.1. Literal expressions(文字表达式)

子类又细分为以下类别:

  1. strings
  2. numeric
  3. boolean
  4. null

具体的用法如下:

// string: 输出 --> Hello World@Value("#{ 'Hello World' }")private String stringHello;// numeric - double: 输出 --> 6.0221415e+23@Value("#{ 6.0221415E+23 }")private double numbericDouble;// numeric - hex: 输出 --> 2147483647@Value("#{ 0x7FFFFFFF }")private int numbericInt;// boolean: 输出 --> true@Value("#{ true }")private boolean numberBoolean;// null: 输出 --> null值@Value("#{ null }") private Integer numberNull;

3.2. Types expressions

具体用法如下:
1. 使用特殊操作符T指定java.lang.Class实例
2. 对于java.lang下面的类, T()可以不指定全限定名称
3. T也可以用于调用静态方法

// T指定java.lang.Class实例: 输出 --> java.util.Date@Value("#{ T(java.util.Date)}")private Class<?> tDate;// 对于java.lang下面的类, T()可以不指定全限定名称: 输出 --> java.lang.String@Value("#{ T(String)}")private Class<?> tLangString;// 调用类的静态方法: 输出 --> true@Value("#{ T(java.math.RoundingMode).CEILING < T(java.math.RoundingMode).FLOOR }")private boolean tStaticMethod;

3.3. Accessing properties

Accessing properties

// 访问对象inventor的属性name: 输出 --> name@Value("#{ inventor.name }") private String propertiesGetObjectMethod;// 调用对象inventor的成员变量birthdate的getYear()方法: 输出 --> 2017@Value("#{ inventor.birthdate.Year + 1900}")private int propertiesGetObjectMemberMethod;

3.4. arrays数组

具体用法如下:
1. 通过索引访问数组对象
2. 初始化数组

// 通过索引访问数组对象: 输出 --> inventions_3@Value("#{ inventor.inventions[2] }")private String arraysIndex;// 初始化数组: 输出 -->  [ 1, 2, 3]@Value("#{ new int[]{1,2,3} }")private int[] inlineArray;

3.5. list 列表

具体用法如下:
1. 通过索引获取List的值
2. 注入初始化List对象

// 通过List获取列表的第三个对象的country值: 输出 -->country_list_2@Value("#{ inventor.placeOfBirthList[1].country}")private String listIndexMember;// 注入初始化List对象. {}表示空List : 输出 -->  [ 1,  2,  3, 4]@Value("#{ {1,2,3,4} }")private List<Integer> inlineList;// --

3.6. maps

具体用法如下:
1. 获取map的值
2. 注入初始化map对象

// 获取inventor对象的成员变量map的mapKey_2的值: 输出 --> 2@Value("#{ inventor.map[mapKey_2]}")private int mapKeyValue;// 注入初始化map对象. {}表示空map: 输出 --> {"name": "hry","sex": "man"}@Value("#{ {name:'hry',sex:'man'} }")private Map<String,String> inlineMap;

3.7. Method invocation: 方法调用

具体用法如下:

  1. 调用string的方法
  2. 调用自定义对象的方法
// 调用string的方法: 输出 --> c@Value("#{ 'abc'.substring(2, 3) }")private String methodInvoke;// 调用自定义对象的方法: 输出 --> false@Value("#{ inventor.nameIsSame('name_1') }")private String myObjectmethodInvoke;// --

3.8. Relational operators(关系操作符)

具体用法如下:

  1. equal: (==)
  2. not equal
  3. less than:(<)
  4. less than or equal:(<=)
  5. greater than: (>)
  6. greater than or equal: (>=)
// 相同判断: 输出 --> true@Value("#{ 2 == 2 }") private boolean relationEqual;// 大小比较: 输出 --> false@Value("#{ 2 < -5.0 }")private boolean relationLessThan;

3.9. Logical operators(逻辑操作符)

具体用法如下:

  1. and
  2. or
  3. not (!).
// and操作符: 输出 --> false@Value("#{ true and false }")private boolean logicalAnd;// or操作符: 输出 --> true@Value("#{ inventor.nameIsSame('name_1') or inventor.nameIsSame('name') }")private boolean logicalOr;// not操作符: 输出 --> false@Value("#{ !true }")private boolean logicalNot;

3.10. Mathematical operators:数学运算符

具体用法如下:

  1. Addition
  2. Subtraction
  3. multiplication
  4. division: (/)
  5. modulus: (%)
  6. exponential power: (^)
// : 输出 --> 2@Value("#{ 1 + 1 }")private int mathematicalAddition;// 加法: 输出 --> 4@Value("#{ 1 - -3 }")private int mathematicalSubtraction;// 减法: 输出 --> 6@Value("#{ -2 * -3 }")private int mathematicalMultiplication;// 除法: 输出 --> -2@Value("#{ 6 / -3 }")private int mathematicalDivision;// 取余: 输出 --> 1@Value("#{ 8 / 5 % 2  }")private int mathematicalModulus;// 指数幂: 输出 --> 8@Value("#{ 2 ^ 3 }")private int mathematicalExponentialPower;

3.11. Ternary operator(三元运算符)

// 三元运算符: 输出 --> falseExp@Value("#{false ? 'trueExp' : 'falseExp'}")private String ternary;

3.12. Safe Navigation operator

如果获取的值没有,则通过?设置默认值

// 如果systemProperties['pop3.port']没有值,通过?指定默认值,避免抛出NullPointerException: 输出 --> 25@Value("#{ systemProperties['pop3.port'] ?: 25 }")private String safeNavigation;

3.13. Collection

具体用法如下:
1. Collection selection(集合选择): 语法.?[selectionExpression]
2. Collection projection(集合投影):语法

// 获取集合中对象placeOfBirth的city等于city_list_2的对象的集合: 输出 --> [{"city": "city_list_2", "country": "country_list_2"}]@Value("#{ inventor.placeOfBirthList.?[city=='city_list_2'] }")private List<PlaceOfBirth> collectionListSelection;// 获取对象Invertor中map的value<2的对象,并生成新的map: 输出 --> {"mapKey_1": "1"}@Value("#{ inventor.map.?[value<2] }")private Map<String, String> collectionMapSelection;// 获取inventor.placeOfBirthList的所有的属性city的值,并组成一个对象: 输出 --> "collectionProjection": ["city_list_1","city_list_2", "city_list_3"]@Value("#{ inventor.placeOfBirthList.![city] }")private List<String> collectionProjection;

4. 相关的代码

4.1. 完整代码

见Github

原创粉丝点击