spring 使用Spring表达式(Spring EL)

  Spring还提供了更灵活的注入方式,那就是Spring表达式,实际上Spring EL远比以上注入方式强大,咱们须要学习它。Spring EL拥有不少功能。
  使用Bean的id来引用Bean。
  •调用指定对象的方法和访问对象的属性。
  •进行运算。
  •提供正则表达式进行匹配。
  •集合配置。
  这些都是Spring表达式的内容,使用Spring表达式能够得到比使用Properties文件更为强大的装配功能,只是有时候为了方便测试可使用Spring EL定义的解析类进行测试,为此咱们先来认识它们。java

Spring EL相关的类

  简要介绍Spring EL的相关类,以便咱们进行测试和理解。首先是ExpressionParser接口,它是一个表达式的解析接口,既然是一个接口,那么它就不具有任何具体的功能,显然Spring会提供更多的实现类正则表达式

  

 

  代码清单:举例说明Spring EL的使用spring

//表达式解析器
ExpressionParser parser = new SpelExpressionParser();
// 设置表达式
Expression exp = parser.parseExpression("'hello world'");
String str = (String) exp.getValue();
System.out.println(str);
//经过EL访问普通方法
exp = parser.parseExpression("'hello world'.charAt(0)");
char ch = (Character) exp.getValue();
System.out.println(ch);
//经过EL访问的getter方法
exp = parser.parseExpression("'hello world'.bytes");
byte[] bytes = (byte[]) exp.getValue();
System.out.println(bytes);
//经过EL访问属性,至关于"hello world".getBytes().length
exp = parser.parseExpression("'hello world'.bytes.length");
int length = (Integer) exp.getValue();
System.out.println(length);
exp = parser.parseExpression("new String('abc')");
String abc = (String) exp.getValue();
System.out.println(abc);

 

//表达式解析器
ExpressionParser parser = new SpelExpressionParser();
//建立角色对象
Role2 role = new Role2(1L, "role_name", "note");
Expression exp = parser.parseExpression("note");
//至关于从role中获取备注信息
String note = (String) exp.getValue(role);
System.out.println(note);
//变量环境类,而且将角色对象role做为其根节点
EvaluationContext ctx = new StandardEvaluationContext(role);
//变量环境类操做根节点
parser.parseExpression("note").setValue(ctx, "new_note");
//获取备注,这里的String.class指明,咱们但愿返回的是一个字符串
note = parser.parseExpression("note").getValue(ctx, String.class);
System.out.println(note);
//调用getRoleName方法
String roleName = parser.parseExpression("getRoleName()").getValue(ctx, String.class);
System.out.println(roleName);
//新增环境变量
List<String> list = new ArrayList<String>();
list.add("value1");
list.add("value2");
//给变量环境增长变量
ctx.setVariable("list", list);
//经过表达式去读/写环境变量的值
parser.parseExpression("#list[1]").setValue(ctx, "update_value2");
System.out.println(parser.parseExpression("#list[1]").getValue(ctx));

 

  EvaluationContext使用了它的实现类StandardEvaluationContext,进行了实例化,在构造方法中将角色对象传递给它了,那么估值内容就会基于这个类进行解析。因此后面表达式的setValue和getValue方法都把这个估值内容传递进去,这样就可以读/写根节点的内容了,而且经过getRole()的例子,还能够知道它甚至可以支持方法的调用。为了更加灵活,估值内容还支持了其余变量的新增和操做,正如代码中建立了一个List,而且把List用估值内容的setVariable方法设置,其键为"list",这样就容许咱们在表达式里面经过#list去引用它,而给出的下标1,则是表明引用List的第二个元素(list是如下标0标识第一个元素的)。
  上面介绍了Spring具备对表达式的解析功能,Spring EL最重要的功能就是对Bean属性进行注入,让咱们以注解的方式为主去学习它们。less

Bean的属性和方法

  使用注解的方式须要用到注解@Value,在属性文件的读取中使用的是“$”,而在Spring EL中则使用“#”。下面以角色类为例进行讨论,咱们能够这样初始化它的属性,如代码清单所示。
  代码清单:使用Spring EL初始化角色类dom

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

@Component("role2")
public class Role2 {

//赋值long型
@Value("#{2}")
private Long id;
//字符串赋值
@Value("#{'role_name_2'}")
private String roleName;
//字符串赋值
@Value("#{'note_2'}")
private String note;
}

 

  代码清单:经过Spring EL引用role的属性,调用其方法学习

@Component("elBean")
public class ElBean {

//经过beanName获取bean,而后注入
@Value("#{role2}")
private Role2 role2;

//获取bean的属性id
@Value("#{role2.id}")
private Long id;

//调用bean的getNote方法,获取角色名称
// @Value("#{role.getNote().toString()}")
@Value("#{role2.getNote()?.toString()}")
private String note;

@Value("#{T(Math).PI}")
private double pi;

@Value("#{T(Math).random()}")
private double random;

@Value("#{role.id+1}")
private int num;
}

 

AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ApplicationConfig3.class);
Role2 role2 = context.getBean(Role2.class);
System.out.println(role2.toString());
ElBean elBean = context.getBean(ElBean.class);
System.out.println(elBean.toString());

 

使用类的静态常量和方法  

  有时候咱们可能但愿使用一些静态方法和常量,好比圆周率π,而在Java中就是Math类的PI常量了,须要注入它十分简单,在ElBean中如同下面同样操做就能够了:
  @Value("#{T(Math).PI}")
  private double pi;
  这里的Math表明的是java.lang.*包下的Math类。当在Java代码中使用该包是不须要先使用import关键字引入的,对于Spring EL也是如此。若是在Spring中使用一个非该包的内容,那么要给出该类的全限定名,须要写成相似这样:
  @Value("#{T(java.lang.Math).PI}")
  private double pi;
  一样,有时候使用Math类的静态方法去生产随机数(0到1之间的随机双精度数字),这个时候就须要使用它的random方法了,好比:
  @Value("#{T(Math).random()}")
  private double random;
  这样就能够经过调用类的静态方法加载对应的数据了。测试

Spring EL运算

  上面讨论了如何获取值,除此以外Spring EL还能够进行运算,好比在ElBean上增长一个数字num,其值默认为要求是角色编号(id)+1,那么咱们就能够写成:lua

  @Value("#{role.id+1}")
  private int num;
  有时候“+”运算符也能够运用在字符串的链接上,好比下面的这个字段,把角色对象中的属性roleName和note相连:
  @Value("#{role.roleName + role.note}")
  private String str;
  这样就可以获得一个角色名称和备注相链接的字符串。比较两个值是否相等,好比角色id是否为1,角色名称是否为"role_name_001"。数字和字符串均可以使用“eq”或者“==”进行相等比较。除此以外,还有大于、小于等数学运算,好比:
  @Value("#{role.id == 1}")
  private boolean equalNum;
  @Value("#{role.note eq 'note_1'}")
  private boolean eqaulString;
  @Value("#{role.id > 2}")
  private boolean greater;
  @Value("#{role.id < 2}")
  private boolean less;
  在Java中,也许你会怀念三目运算,好比,若是角色编号大于1,那么取值5,不然取值1,那么在Java中能够写成:
  int max = (role.getId()>1? 5:1);
  若是角色的备注为空,咱们给它一个默认的初始值“note”,使用Java则写成:  
  String defaultString = (role.getNote() == null? "hello" : role.getNote());
  下面让咱们经过String EL去实现上述的功能。
  @Value("#{role.id > 1 ? 5 : 1}")
  private int max;
  @Value("#{role.note?: 'hello'}")
  private String defaultString;
  实际上Spring EL的功能远不止这些,上面只介绍了一些最基础、最经常使用的功能,熟练运用它还须要读者们多动手实践。spa

 

 

文章来源:ssm10.10code

相关文章
相关标签/搜索