内联List
从Spring3.0.4开始支持内联List,使用{表达式,……}定义内联List,如“{1,2,3}”将返回一个整型的ArrayList,而“{}”将返回空的List,对于字面量表达式列表,SpEL会使用java.util.Collections.unmodifiableList方法将列表设置为不可修改。示例如下:
1://将返回不可修改的空List
List<Integer> result2 = parser.parseExpression("{}").getValue(List.class);
2:对于字面量列表也将返回不可修改的List
ExpressionParser parser = new SpelExpressionParser();
List<Integer> result1 = parser.parseExpression("{1,2,3}").getValue(List. class);
//result1.set(0, 2);//这句话会报错,因为list不可以修改
System. out.println(result1);
3://对于列表中只要有一个不是字面量表达式,将只返回原始List,
//不会进行不可修改处理,也就是可以修改
String expression3 = "{{1+2,2+4},{3,4+4}}";
List<List<Integer>> result3 = parser.parseExpression(expression3).getValue(List.class);
result3.get(0).set(0, 1);
内联数组
和Java 数组定义类似,只是在定义时进行多维数组初始化。 示例如下:
1://定义一维数组并初始化
int[] result1 = parser.parseExpression("new int[1]").getValue(int[].class);
2://声明二维数组并初始化
int[] result2 = parser.parseExpression("new int[2]{1,2}").getValue(int[].class);
3://定义多维数组但不初始化
int[][][] result3 = parser.parseExpression(expression3).getValue(int[][][].class);
4://错误的定义多维数组,多维数组不能初始化
String expression4 = "new int[1][2][3]{{1}{2}{3}}";
int[][][] result4 = parser.parseExpression(expression4).getValue(int[][][].class);
访问元素
SpEL目前支持所有集合类型和字典类型的元素访问,使用“集合[索引]”访问集合元素,使用“map[key]”访问字典元素 。示例如下;
1://SpEL内联List访问
int result1 = parser.parseExpression("{1,2,3}[0]").getValue(int.class);
//相当于result1.get(0)
2://SpEL目前支持所有集合类型的访问
Collection<Integer> collection = new HashSet<Integer>();
collection.add(1);
collection.add(2);
EvaluationContext context2 = new StandardEvaluationContext();
context2.setVariable("collection", collection);
int result2 = parser.parseExpression("#collection[1]").getValue(context2, int.class);
3://SpEL对Map字典元素访问的支持
Map<String, Integer> map = new HashMap<String, Integer>();
map.put("a", 1);
EvaluationContext context3 = new StandardEvaluationContext();
context3.setVariable("map", map);
int result3 = parser.parseExpression("#map['a']").getValue(context3, int.class);
元素修改
可以使用赋值表达式或Expression接口的setValue方法修改。示例如下:
1://修改数组元素值
int[] array = new int[] {1, 2};
EvaluationContext context1 = new StandardEvaluationContext();
context1.setVariable("array", array);
int result1 = parser.parseExpression("#array[1] = 3").getValue(context1, int.class);
2://修改集合值
Collection<Integer> collection = new ArrayList<Integer>();
collection.add(1);
collection.add(2);
EvaluationContext context2 = new StandardEvaluationContext();
context2.setVariable("collection", collection);
int result2 = parser.parseExpression("#collection[1] = 3").getValue(context2, int.class);
parser.parseExpression("#collection[1]").setValue(context2, 4);
result2 = parser.parseExpression("#collection[1]").getValue(context2, int.class);
3://修改map元素值
Map<String, Integer> map = new HashMap<String, Integer>();
map.put("a", 1);
EvaluationContext context3 = new StandardEvaluationContext();
context3.setVariable("map", map);
int result3 = parser.parseExpression("#map['a'] = 2").getValue(context3, int.class);
集合投影
在SQL中投影指从表中选择出列,而在SpEL指从集合中的元素,通过选择来构造新的集合,该集合和原集合具有相同数量的元素,但可能属性不一样;SpEL使用“(list|map).![投影表达式]”来进行投影运算。
1:示例集合的投影
//1.首先准备测试数据
Collection<UserModel> collection = new ArrayList<UserModel>();
UserModel um1 = new UserModel();
um1.setUuid("u1");
um1.setName("u1Name");
collection.add(um1);
UserModel um2 = new UserModel();
um2.setUuid("u2");
um2.setName("u2Name");
collection.add(um2);
//2.测试集合或数组
EvaluationContext context1 = new StandardEvaluationContext();
ExpressionParser parser = new SpelExpressionParser();
context1.setVariable("collection", collection);
Collection<String> result1 =
parser.parseExpression(" #collection.![#this.name]").getValue(context1, Collection.class);
SpEL投影运算还支持Map投影,但Map投影最终只能得到List结果,对于投影表达式中的“#this”将是Map.Entry,所以可以使用“value”来获取值,使用“key”来获取键。 示例如下:
//1.首先准备测试数据
java代码:- UserModel um1 = new UserModel();
- um1.setUuid("u1");
- um1.setName("u1Name");
- UserModel um2 = new UserModel();
- um2.setUuid("u2");
- um2.setName("u2Name");
- Map<String, UserModel> map = new HashMap<String, UserModel>();
- map.put(um1.getUuid(),um1);
- map.put(um2.getUuid(),um2);
- //2.测试Map投影
- EvaluationContext context1 = new StandardEvaluationContext();
- ExpressionParser parser = new SpelExpressionParser();
- context1.setVariable("map", map);
- Collection<String> result1 =
- parser.parseExpression("#map.![#this.value.name]").getValue(context1, Collection.class);
集合筛选
在SpEL指根据原集合通过条件表达式选择出满足条件的元素并构造为新的集合,SpEL使用“(list|map).?[选择表达式]”,其中选择表达式结果必须是boolean类型,如果true则选择的元素将添加到新集合中,false将不添加到新集合中。示例如下:
//1:准备测试数据的过程跟上一个示例一样,就不重复了
//2.测试集合或数组的筛选
java代码:- EvaluationContext context1 = new StandardEvaluationContext();
- ExpressionParser parser = new SpelExpressionParser();
- context1.setVariable("collection", collection);
- Collection<String> result1 =
- parser.parseExpression("#collection.?[#this.uuid.equals('u1')]").getValue(context1, Collection.class);
-
//测试Map筛选
java代码:- EvaluationContext context1 = new StandardEvaluationContext();
- ExpressionParser parser = new SpelExpressionParser();
- context1.setVariable("map", map);
- Map<String,UserModel> result1 =
- parser.parseExpression("#map.?[#this.key=='u1']").getValue(context1, Map.class);
nXml风格的配置
SpEL支持在Bean定义时使用,默认使用“#{SpEL表达式}”表示,不允许嵌套。其中“#root”根对象默认可以认为是ApplicationContext,获取根对象属性其实是获取容器中的Bean。
nXml风格的配置示例----通过SpEL表达式设置值
java代码:- <bean id="numberGuess" class="org.spring.samples.NumberGuess">
- <property name="randomNumber" value="#{ T(java.lang.Math).random() * 100.0 }"/>
- </bean>
Xml风格的配置示例----通过SpEL表达式参照其他的Bean
java代码:- <bean id="t1" class="cn.javass.spring3.hello.T2">
- <property name="value" value="#{ T(java.lang.Math).random() * 100.0 }"/>
- </bean>
- <bean id="t2" class="cn.javass.spring3.hello.T2">
- <property name="value" value="#{ T(Double).parseDouble(t1.value) -1 }"></property>
- </bean>
上面的t1就会被解析成为参照t1这个Bean,当然也可以使用@t1来表示。
注解风格的配置
使用@Value注解来指定SpEL表达式,该注解可以放到字段、方法及方法参数上。 但是要在配置文件中使用<context:annotation-config/> 来开启对注解的支持。示例如下:
java代码:- public class SpELBean {
- @Value("#{ T(java.lang.Math).random() * 100.0 }")
- private String value;
- //setter和getter由于篇幅省略,自己写上
- }
注意:如果同时使用了@Value和setter注入,那么setter注入将覆盖@Value的值。