今天看啥  ›  专栏  ›  hryou0922

Spring SpEL系列二 @Value,xml, Java代码使用SpEL

hryou0922  · 掘金  ·  · 2018-01-22 02:31

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代码




原文地址:访问原文地址
快照地址: 访问文章快照