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

相關文章
相關標籤/搜索