Spring還提供了更靈活的注入方式,那就是Spring表達式,實際上Spring EL遠比以上注入方式強大,咱們須要學習它。Spring EL擁有不少功能。
使用Bean的id來引用Bean。
•調用指定對象的方法和訪問對象的屬性。
•進行運算。
•提供正則表達式進行匹配。
•集合配置。
這些都是Spring表達式的內容,使用Spring表達式能夠得到比使用Properties文件更爲強大的裝配功能,只是有時候爲了方便測試可使用Spring EL定義的解析類進行測試,爲此咱們先來認識它們。java
簡要介紹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
使用註解的方式須要用到註解@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還能夠進行運算,好比在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