2016年1月4日 星期一

SpEL1 (Spring3.x 十五)

參考文件


※基本

ExpressionParser parser = new SpelExpressionParser();
    
Expression exp = parser.parseExpression("'Hello World'");
String message = (String) exp.getValue();
System.out.println(message);
    
Expression exp2 = parser.parseExpression("new String('Hello World')");
String message2 = exp2.getValue(String.class);
System.out.println(message2);
    
System.out.println(parser.parseExpression("'Hello World'.concat('!')").getValue());
System.out.println(parser.parseExpression("'Hello World' + 'Mary' ").getValue());
System.out.println(parser.parseExpression("'Hello World'.replace('World', 'Mary')").getValue());
    
Expression b = parser.parseExpression("'Hello World'.bytes");
byte[] bytes = (byte[]) b.getValue();
System.out.println(bytes[1]);// 101-->e的ascii為101

※結果:
Hello World
Hello World
Hello World!
Hello WorldMary
Hello Mary
101

※在parseExpression("")裡面的空間就好像是寫java的環境一樣(也類似javascript的eval()),可以把它想像成Eclipse,所以字一定要用「"」或「'」包起來,而最外面已經是「"」了,所以只好用跳脫字元「\"」或「'」

※exp要強轉,exp2已經寫在getValue裡了,所以可以不用強轉

※裡面已經是eclipse了,所以eclipse怎麼操作,裡面就怎麼操作




※取得屬性

XXX.java

public class XXX {
    public String ooo = "OOO";
}



測試類

ExpressionParser p1 = new SpelExpressionParser();
Expression e = p1.parseExpression("ooo");
EvaluationContext context = new StandardEvaluationContext(new XXX());
System.out.println(e.getValue(context));
    
Expression ex1 = p1.parseExpression("ooo == 'OOO'");
Expression ex2 = p1.parseExpression("ooo.equals('OOO')");
System.out.println(ex1.getValue(context, Boolean.class));
System.out.println(ex2.getValue(context, Boolean.class));
    
ExpressionParser p2 = new SpelExpressionParser();
Expression exp = p2.parseExpression("ooo");
System.out.println(exp.getValue(new XXX()));
    
Expression ex3 = p2.parseExpression("ooo == 'OOO'");
Expression ex4 = p2.parseExpression("ooo.equals('OOO')");
System.out.println(ex3.getValue(new XXX(), Boolean.class));
System.out.println(ex4.getValue(new XXX(), Boolean.class));

※結果:
OOO
true
true
OOO
true
true

※p1多一個EvaluationContext,然後new個建構子在裡面; 而p2直接將建構子放在getValue裡



※取代

XXX.java

public class XXX {
    public List<String> ooo = new ArrayList<String>();
}



測試類

XXX xxx = new XXX();
xxx.ooo.add("abc");
StandardEvaluationContext context = new StandardEvaluationContext(xxx);
    
// new SpelExpressionParser().parseExpression("ooo[0]").setValue(context, "def");
System.out.println(xxx.ooo.get(0));

※將註解那行打開就可以取代了,但只能取代,不能新增



另一種方式

List<String> aaa = new ArrayList<String>();
aaa.add("ghi");
    
EvaluationContext ec = new StandardEvaluationContext(aaa);
ec.setVariable("listAaa", aaa);
    
new SpelExpressionParser().parseExpression("#listAaa[0]").setValue(ec, "jkl");
System.out.println(aaa.get(0));

※這種方式是在EvaluationContext設定一個變數名稱,使用時必須在前前加上「#」




※XML

Book.java和Comic.java

public class Book {
    private Double randomPrice1;
    private Double randomPrice2;
    private String display;
    private String copy;
    // setter/getter...
}
    
public class Comic {
    private String comicName;
    // setter/getter...
}



applicationContext.xml

<bean id="co" class="vo.Comic" p:comicName="#{'七龍珠a'}" />
    
<bean id="bo" class="vo.Book" p:display="#{systemProperties['java.vendor.url']}">
    <property name="randomPrice1" value="#{T(java.lang.Math).random() * 100.0}" />
    <property name="randomPrice2" value="#{T(java.lang.Double).valueOf(T(java.lang.Math).random() * 100.0).intValue()}" />
    <property name="copy" value="#{co.comicName.toUpperCase()}" />
</bean>



測試類

ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
    
System.out.println(ctx.getBeanDefinitionCount());
for (String s : ctx.getBeanDefinitionNames()) {
    System.out.println(s);
}
    
Book book1 = ctx.getBean("bo", Book.class);
    
System.out.println(book1.getRandomPrice1());
System.out.println(book1.getRandomPrice2());
System.out.println(book1.getDisplay());
System.out.println(book1.getCopy());
    
((ClassPathXmlApplicationContext) ctx).close();

※結果:
2
co
bo
64.00558669972638
83.0
http://java.oracle.com/
七龍珠A

※在XML裡一律都用「#{}」,語法寫在裡面

※randomPrice1小數點後面很多,而randomPrice2用T(java.lang.Double).valueOf().intValue()可以去掉小數點

※display的systemProperties['java.vendor.url'],裡面的字,可以用System.getProperties().list(System.out);,印出來是key=value,裡面的字打key,顯示出來就是value的值

※copy可以直接取id裡面的屬性,然後還可以再「.」方法

※方法之前不用「()」,現在都要加



※取得properties 

kv.properties

key=value
a=apple
b=blueberry



applicationContext.xml

<util:properties id="keyValue" location="classpath:kv.properties" />
    
<bean id="bo" class="vo.Book" >
    <property name="copy" value="#{keyValue.a.toUpperCase()}" />
</bean>





※Annotation

applicationContext.xml要開啟<context:component-scan base-package="\">


Comic.java

@Component("co")
public class Comic {
    @Value("七龍珠a")
    private String comicName;
    // setter/getter...
}



Book.java

@Component("bo")
public class Book {
    @Value("#{T(java.lang.Math).random() * 100.0}")
    private Double randomPrice1;
    
    @Value("#{T(java.lang.Double).valueOf(T(java.lang.Math).random() * 100.0).intValue()}")
    private Double randomPrice2;
    
    @Value("#{systemProperties['java.vendor.url']}")
    private String display;
    
    @Value("#{co.comicName.toUpperCase()}")
    private String copy;
    
    // setter/getter...
}

※剛剛的xml設定變成Annotation後變成這樣子,@Value也可以寫在setter上


沒有留言:

張貼留言