相對來講, java是一門靜态語言。而我們今天要講的是一門動态“語言”---SpEL。
動态語言和靜态語言的最顯著差别在于,舉個例子," 'Hello'.toUperCase()"這隻是一個普通的字元串,差别在
于能否把它編譯和運作起來得到結果。就是說動态語言能把一個字元串解釋成程式語句。如果還不是很明白的
話沒關系,看下面的SpEL例子。(接下去的我就用例子來做介紹了)
public void testSpEL1() {
//ExpressionParser是Spring3裡的一個包,用來動态解釋一個字元串。
ExpressionParser parser = new SpelExpressionParser();
Expression exp = parser.parseExpression(" 'Hello,World' ");
System.out.println((String)exp.getValue());
}
這裡'Hello,World' 是一個字元串,解釋起來還是一個字元串,是以列印結果是:Hello,World
第二個例子:調用方法
public void testSpEL2() {
ExpressionParser parser = new SpelExpressionParser();
Expression exp=parser.parseExpression(" 'Hello'.concat(' World!')"); //這裡調用了字元串String的concat方法
//Expression exp=parser.parseExpression("newString('helloworld').toUpperCase()");
Stringmessage=(String)exp.getValue();
}
第三個例子:調用屬性
ExpressionParser parser= new SpelExpressionParser();
Expression exp=parser.parseExpression("'HelloWorld'.bytes"); //得到字元串的byte
//Expression exp=parser.parseExpression("'HelloWorld'.bytes.length"); //得到屬性的屬性
byte [] bytes=(byte[])exp.getValue();
第四個例子:調用類中的屬性(下面開始複雜起來了)
@Resource
public User user; //注入之後,user.getName() 為 xiaoling
public void testSpEL() {
//設“值域”,限定在u這個對象裡
EvaluationContext context = new StandardEvaluationContext(user);
ExpressionParser parser = new SpelExpressionParser();
Expression exp = parser.parseExpression("username"); //==user.getUsername()
System.out.println((String)exp.getValue(context)); //結果:xiaoling
}
或者用更簡潔的一個方式:
System.out.println((String)exp.getValue(user));
這樣就不用設值域了!呵呵!
第五個例子:給對象中的屬性設值
StandardEvaluationContext context = new StandardEvaluationContext(user);
parser.parseExpression("username").setValue(context, "ling");
第六個例子:做判斷
Expression exp=parser.parseExpression("name=='xiaoling' ");
boolean result=exp.getValue(context,Boolean.class); //evaluate stotrue
列印出來,結果為true
看到這,可能你還是一頭霧水:這算什麼新特性啊,哪有什麼用處!
用處就在于,SpEL把java變成“動”的了!(純屬我個人觀點!!)
接下來,我們把SpEL用到bean.xml中去
先看個例子(例一)
<bean id="numberGuess" class="cn.ling.spel.NumberGuess">
<property name="randomNumber" value="#{T(java.lang.Math).random()*100.0}"/>
</bean>
怎麼樣,可以在xml檔案裡面指派了!呵呵!
value裡面都用#{}來指派。至于T(java.lang.Math),它是指某個類,即Math這個類。
看這個例子(例二):systemProperties
<propertyname="defaultLocale"value="#{systemProperties['user.region']}"/>
systemProperties是預定義好的,裡面有很屬性可以用,它就相當于java檔案中的System.getProperty("user.region"),它能取出目前計算機所在的國家。
例三:引用xml裡面的其它bean
<bean id="numberGuess" class="org.spring.samples.NumberGuess">
<property name="randomNumber" value="#{T(java.lang.Math).random()*100.0}"/>
<!--otherproperties-->
</bean>
<bean id="shapeGuess" class="org.spring.samples.ShapeGuess">
<property name="initialShapeSeed" value="#{numberGuess.randomNumber}"/>
<!--otherproperties-->
</bean>
SpEL還可以用在annotation中:
例一:用在屬性上
public static class FieldValueTestBean{
@Value("#{systemProperties['user.region']}")
private String defaultLocale;
//set和get方法
public void setDefaultLocale(StringdefaultLocale) {
this.defaultLocale=defaultLocale;
}
public StringgetDefaultLocale(){
returnthis.defaultLocale;
}
}
例二:用在方法上
public static class PropertyValueTestBean{
private String defaultLocale;
@Value("#{systemProperties['user.region']}")
public void setDefaultLocale(String defaultLocale){
this.defaultLocale=defaultLocale;
}
public String getDefaultLocale(){
return this.defaultLocale;
}
}
}
例三:Autowired和構造器中
public class SimpleMovieLister{
private MovieFinder movieFinder;
private String defaultLocale;
@Autowired
public void configure(MovieFinder movieFinder,
@Value("#{systemProperties['user.region']}"}String defaultLocale){
this.movieFinder=movieFinder;
this.defaultLocale=defaultLocale;
}
//...
}