public class SpelTest { public static void main(String[] args){ //创建解析器 ExpressionParser parser=new SpelExpressionParser(); //解析表达式 Expression expression= parser.parseExpression("('Hello'+'World').concat(#end)"); //构造上下文 EvaluationContext context=new StandardEvaluationContext(); //为end参数值来赋值 context.setVariable("end","!"); //打印expression表达式的值 System.out.println(expression.getValue(context)); } }
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd "> <bean id="world" class="java.lang.String"> <constructor-arg value="#{' World!'}"/> </bean> <!--方式一--> <bean id="hello1" class="java.lang.String"> <constructor-arg value="#{'Hello '}#{world}"/> </bean> <!--方式二 注意:Spring语言不支持嵌套,即在一个#之内又有一个# <constructor-arg value="#{'Hello '#{world}}"/>--> <bean id="hello2" class="java.lang.String"> <constructor-arg value="#{'Hello '+world}"/> </bean> <!--方式三--> <bean id="hello3" class="java.lang.String"> <constructor-arg value="#{'Hello '+@world}"/> </bean> </beans>
public class XmlExpression { public static void main(String[] args){ ApplicationContext ctx= new FileSystemXmlApplicationContext("src/conf/conf-spel.xml"); String hello1=ctx.getBean("hello1",String.class); String hello2=ctx.getBean("hello2",String.class); String hello3=ctx.getBean("hello3",String.class); System.out.println(hello1); System.out.println(hello2); System.out.println(hello3); } }
<!--开启注解支持--> <context:annotation-config/> <bean id="hellobean1" class="cn.lovepi.chapter05.spel.AnnoExpression"/> <bean id="hellobean2" class="cn.lovepi.chapter05.spel.AnnoExpression"> <property name="value" value="haha"/> </bean>
public class AnnoExpression { @Value("#{'Hello '+world}") private String value; public String getValue() { return value; } public void setValue(String value) { this.value = value; } public static void main(String[] args){ ApplicationContext ctx= new FileSystemXmlApplicationContext("src/conf/conf-spel.xml"); AnnoExpression hellobean1=ctx.getBean("hellobean1",AnnoExpression.class); AnnoExpression hellobean2=ctx.getBean("hellobean2",AnnoExpression.class); System.out.println(hellobean1.getValue()); System.out.println(hellobean2.getValue()); } }
public class SpelLiteral { private int count; private String message; private float frequency; private float capacity; private String name1; private String name2; private boolean enabled; public int getCount() { return count; } public void setCount(int count) { this.count = count; } public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } public float getFrequency() { return frequency; } public void setFrequency(float frequency) { this.frequency = frequency; } public float getCapacity() { return capacity; } public void setCapacity(float capacity) { this.capacity = capacity; } public String getName1() { return name1; } public void setName1(String name1) { this.name1 = name1; } public String getName2() { return name2; } public void setName2(String name2) { this.name2 = name2; } public boolean isEnabled() { return enabled; } public void setEnabled(boolean enabled) { this.enabled = enabled; } }可以看到该Bean有很多基本数据类型以及String类型的属性,接下来我们一一在配置文件中为这些属性使用Spring表达式语言赋值
<bean id="spelliteral" class="cn.lovepi.chapter05.spel.SpelLiteral"> <property name="count" value="#{5}"/> <property name="message" value="The value is #{5}"/> <property name="frequency" value="#{89.7}"/> <property name="capacity" value="#{1e4}"/> <property name="name1" value="#{'wang'}"/> <property name="name2" value='#{"wang"}'/> <property name="enabled" value="#{false}"/> </bean>
public class SpelMain { public static void main(String[] args){ testSpelLiteral(); } private static void testSpelLiteral(){ ApplicationContext ctx= new FileSystemXmlApplicationContext("src/conf/conf-spel.xml"); SpelLiteral literal=ctx.getBean("spelliteral",SpelLiteral.class); System.out.println("count= "+literal.getCount()); System.out.println("message= "+literal.getMessage()); System.out.println("frequency= "+literal.getFrequency()); System.out.println("capacity= "+literal.getCapacity()); System.out.println("name1= "+literal.getName1()); System.out.println("name2= "+literal.getName2()); System.out.println("enabled= "+literal.isEnabled()); } }
<property name="bean2" value="#{bean1}"/>这句话等价与
<property name="bean2" ref="bean1"/>
<bean id="bean2" class="cn.lovepi.***"> <property name="name" value="#{bean1.name}"/> </bean>
Bean2 bean2=new Bean2(); bean2.setName(bean1.getName());
<property name="name" value="#{bean1.getName()}/>还可以将获取到的name值转换为大写
<property name="name" value="#{bean1.getName().toUpperCase()}/>
<property name="name" value="#{bean1?.getName().toUpperCase()}/>
public class SpelClass { private float pi; private float randomNumber; public float getPi() { return pi; } public void setPi(float pi) { this.pi = pi; } public float getRandomNumber() { return randomNumber; } public void setRandomNumber(float randomNumber) { this.randomNumber = randomNumber; } }为其编写配置文件
<bean id="spelClass" class="cn.lovepi.chapter05.spel.SpelClass"> <property name="pi" value="#{T(java.lang.Math).PI}"/> <property name="randomNumber" value="#{T(java.lang.Math).random()}"/> </bean>
private static void testSpelClass(){ ApplicationContext ctx= new FileSystemXmlApplicationContext("src/conf/conf-spel.xml"); SpelClass spelClass=ctx.getBean("spelClass",SpelClass.class); System.out.println("PI="+spelClass.getPi()); System.out.println("randomNumber="+spelClass.getRandomNumber()); }
运算符类型 |
运算符示例
|
数值运算 | +、-、*、/、%、^(乘方运算) |
比较运算 | <(lt)、>(gt)、==(eg)、<=(le)、>=(ge) |
逻辑运算 | and、or、not、| |
条件运算 | ?:(ternary)、?:(Elvis) |
正则表达式 | matches |
public class SpelCounter { private float total; private float count; public float getTotal() { return total; } public void setTotal(float total) { this.total = total; } public float getCount() { return count; } public void setCount(float count) { this.count = count; } }接下来创建一个运算演示Bean
public class SpelMath { private float ajustedAcount; private float circumFference; private float average; private float remainder; private float area; private String fullName; public float getAjustedAcount() { return ajustedAcount; } public void setAjustedAcount(float ajustedAcount) { this.ajustedAcount = ajustedAcount; } public float getCircumFference() { return circumFference; } public void setCircumFference(float circumFference) { this.circumFference = circumFference; } public float getAverage() { return average; } public void setAverage(float average) { this.average = average; } public float getRemainder() { return remainder; } public void setRemainder(float remainder) { this.remainder = remainder; } public float getArea() { return area; } public void setArea(float area) { this.area = area; } public String getFullName() { return fullName; } public void setFullName(String fullName) { this.fullName = fullName; } }
<bean id="spelCounter" class="cn.lovepi.chapter05.spel.SpelCounter"> <property name="count" value="#{10}"/> <property name="total" value="#{100}"/> </bean> <bean id="spelMath" class="cn.lovepi.chapter05.spel.SpelMath"> <!--加法运算符--> <property name="ajustedAcount" value="#{spelCounter.total+53}"/> <!--乘法运算符--> <property name="circumFference" value="#{2*T(java.lang.Math).PI*spelCounter.total}"/> <!--除法运算符--> <property name="average" value="#{spelCounter.total/spelCounter.count}"/> <!--取余运算符--> <property name="remainder" value="#{spelCounter.total%spelCounter.count}"/> <!--乘方运算符--> <property name="area" value="#{T(java.lang.Math).PI * spelCounter.total^2}"/> <!--字符串拼接--> <property name="fullName" value="#{'icarus'+' '+'wang'}"/> </bean>接下来在程序入口出测试程序运行结果
private static void testSpelMath(){ ApplicationContext ctx= new FileSystemXmlApplicationContext("src/conf/conf-spel.xml"); SpelMath math=ctx.getBean("spelMath",SpelMath.class); System.out.println("AjustedAcount= "+math.getAjustedAcount()); System.out.println("CircumFference= "+math.getCircumFference()); System.out.println("Average= "+math.getAverage()); System.out.println("Area= "+math.getArea()); System.out.println("Remainder= "+math.getRemainder()); System.out.println("FullName= "+math.getFullName()); }
<property name="name" value="#{person.name!=null ? person.name : 'icarus'}"/>但上面的的语句重复使用了两次person.name属性,SpEL为我们提供了一种更简便的方式:
<property name="name" value="#{person.name!=null ?: 'icarus'}"/>
<property name="validEmail" value="#{admin.email matches '[0-9A-Za-z_%.*+-]+@[0-9A-Za-z.-]+\\.com'}"/>
public class SpelCity{ private String name; private String state; private int population; }接下来我们创建一个集合,集合中的元素是SpelCity
<util:list id="cities"> <bean class="cn.lovepi.***.SpelCity"> <p:name="Chicago" p:state="IL" p:population="2853114"> <bean class="cn.lovepi.***.SpelCity"> <p:name="LasCryces" p:state="NM" p:population="91865"> </util:list>
<property name="bigCities" value="#{cities.?[population gt 100000]}"/>
<property name="cityName1" value="#{cities.![name]}}"/>
<property name="cityName2" value="#{cities.![name+','+state]}}"/>
<property name="cityName3" value="#{cities.?[population gt 100000].![name+','+state]}}"/>