1. 概述
在上文Spring SpEL系列一 基础用法中,通过@Value演示如何使用Spring EL。Spring除了使用@Value,还可以使用xml和java代码直接调用Spring EL。
下文分别使用以上三种方式实现以下功能:
1. 调用String的concat方法
2. 调用JavaBean的属性
3. 访问对象公共属性
4. 获取People的name值,
5. 比较name值是不是hry的结果
以下例子中会使用到的公共类:
public class People{
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
2. 测试代码
2.1 @Value
这是使用最多的场景 SpELAnnotationExample 直接通过@value注入Spring EL表达式的值,详细见代码。
@Component
public class SpELAnnotationExample {
@Value("#{ 'Hello World'.concat('!') }")
private String stringMethod; // 调用String的concat方法
@Value("#{ T(java.util.Arrays).toString('Hello World'.bytes) }")
private String javaBeanProperties; // 调用JavaBean的属性,如这里实际是调用getBytes()方法
@Value("#{ 'Hello World'.bytes.length }")
private long publicAttr; // 访问对象公共属性
@Value("#{ people.name }")
private String objName; // 获取People的name值,比较name值是不是hry
@Value("#{ people.name=='hry' }")
private boolean objNamecmp; // 比较name值是不是hry人结果
@Override
public String toString(){
return JSON.toJSONString(this);
}
// set/get略
}
SpELAnnotationApplication 启动类: 通过 @Configurable初始化People对象,用于@value的对象属性注入的来源。
@SpringBootApplication
@Configurable
public class SpELAnnotationApplication {
public static void main(String[] args) {
SpringApplication.run(SpELAnnotationApplication.class, args);
}
/**
* 初始化对象
* @return
*/
@Bean("people")
public People getPeople(){
People people = new People();
people.setName("hry");
return people;
}
}
测试类
@RunWith(SpringRunner.class)
@SpringBootTest(classes=SpELAnnotationApplication.class)
public class SpELAnnotationExampleTest {
@Autowired
private SpELAnnotationExample spELAnnotationExample;
@Test
public void println(){
System.out.println(spELAnnotationExample.toString());
}
}
测试结果输出:
{"javaBeanProperties":"[72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100]","objName":"hry","objNamecmp":true,"publicAttr":11,"stringMethod":"Hello World!"}
2.2 xml
在xml中使用Spring EL,多使用在配置xml中。
定义POJO类:SpELXMLExample
public class SpELXMLExample {
private String stringMethod; // 调用String的concat方法
private String javaBeanProperties; // 调用JavaBean的属性,如这里实际是调用getBytes()方法
private long publicAttr; // 访问对象公共属性
private String objName; // 获取People的name值,比较name值是不是hry
private boolean objNamecmp; // 比较name值是不是hry人结果
@Override
public String toString(){
return JSON.toJSONString(this);
}
// set/get略
}
spel.xml:xml配置文件,实例化People和对SpELXMLExample的属性注入。
<bean id="spELXMLExample" class="com.hry.spring.spel.multiway.xml.SpELXMLExample">
<!-- 调用String的concat方法 -->
<property name="stringMethod" value="#{ 'Hello World'.concat('!') }"></property>
<!-- 调用JavaBean的属性,如这里实际是调用getBytes()方法 -->
<property name="javaBeanProperties" value="#{ T(java.util.Arrays).toString('Hello World'.bytes) }"></property>
<!-- 访问对象公共属性 -->
<property name="publicAttr" value="#{ 'Hello World'.bytes.length }"></property>
<!-- 获取People的name值 -->
<property name="objName" value="#{ people.name }"></property>
<!-- 比较name值是不是hry人结果 -->
<property name="objNamecmp" value="#{ people.name=='hry' }"></property>
</bean>
<!-- people对象 -->
<bean id="people" class="com.hry.spring.spel.multiway.People">
<property name="name" value="hry"></property>
</bean>
SpELXmlApplication:启动类
@SpringBootApplication
@ImportResource("classpath:/com/hry/spring/spel/multiway/xml/spel.xml")
public class SpELXmlApplication {
public static void main(String[] args) {
SpringApplication.run(SpELXmlApplication.class, args);
}
}
测试类:
@RunWith(SpringRunner.class)
@SpringBootTest(classes=SpELAnnotationApplication.class)
public class SpELAnnotationExampleTest {
@Autowired
private SpELAnnotationExample spELAnnotationExample;
@Test
public void println(){
System.out.println(spELAnnotationExample.toString());
}
}
测试输出:
{"javaBeanProperties":"[72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100]","objName":"hry","objNamecmp":true,"publicAttr":11,"stringMethod":"Hello World!"}
2.3 java代码直接调用Spring EL
此方法比较少用。通过java代码实现Spring EL表达式。
SpELProgramingExample :直接通过Java代码注入Spring EL表达式的值
/**
* 通过程序代码实现调用Spring EL
*
* @author hry
*
*/
@Component
public class SpELProgramingExample {
private String stringMethod; // 调用String的concat方法
private String javaBeanProperties; // 调用JavaBean的属性,如这里实际是调用getBytes()方法
private long publicAttr; // 访问对象公共属性
private String objName; // 获取People的name值,比较name值是不是hry
private boolean objNamecmp; // 比较name值是不是hry人结果
// 初始化值
public void init(){
// 调用String的concat方法
ExpressionParser parser = new SpelExpressionParser();
Expression exp = parser.parseExpression("'Hello World'.concat('!')");
stringMethod = (String) exp.getValue();
// 调用JavaBean的属性,如这里实际是调用getBytes()方法
// SpEL also supports nested properties using standard dot notation, i.e. prop1.prop2.prop3 and the setting of property values
exp = parser.parseExpression("'Hello World'.bytes"); // invokes 'getBytes()'
byte[] bytes = (byte[]) exp.getValue();
javaBeanProperties = Arrays.toString(bytes);
// 访问对象公共属性
// Public fields may also be accessed.
exp = parser.parseExpression("'Hello World'.bytes.length"); // invokes 'getBytes().length'
publicAttr = exp.getValue(Integer.class); // 指定返回的类型
// 获取People的name值,比较name值是不是hry
People people = new People();
people.setName("hry");
EvaluationContext context = new StandardEvaluationContext(people);
exp = parser.parseExpression("name");
objName = exp.getValue(context, String.class); //
exp = parser.parseExpression("name == 'hry'"); // 不带''表示变量, 带''表示字符串
objNamecmp = exp.getValue(context, Boolean.class); //
}
@Override
public String toString(){
return JSON.toJSONString(this);
}
// set/get略
}
SpELProgramingApplication:启动类
@SpringBootApplication
@Configurable
public class SpELProgramingApplication {
public static void main(String[] args) {
SpringApplication.run(SpELProgramingApplication.class, args);
}
}
测试类
@RunWith(SpringRunner.class)
@SpringBootTest(classes=SpELProgramingApplication.class)
public class SpELProgramingExampleTest {
@Autowired
private SpELProgramingExample spELProgramingExample;
@Test
public void println(){
spELProgramingExample.init();
System.out.println(spELProgramingExample.toString());
}
}
测试结果输出
{"javaBeanProperties":"[72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100]","objName":"hry","objNamecmp":true,"publicAttr":11,"stringMethod":"Hello World!"}
2.4 总结
以上三种方式,尽管配置方式有所不同,但是输出的结果是一模一样的
3. 代码
见github代码