SpEL 实例

SpEl 实例

  • 基于 Spring 解析
@RestController
@RequestMapping("/spel")
@Slf4j
public class SpELController implements ApplicationRunner {
	/**
	 *	1)字面值
	 */
	@Value("#{ 'zxd' }")
	private String name;
	@Value("#{ 29 }")
	private int age;
	@Value("#{ true }")
	private boolean male;
	@Value("#{ 15505883728L }")
	private long phone;

	/**
	 * org.springframework.beans.factory.config.BeanExpressionContext
	 *	2)对象属性
	 */
	@Value("#{ beanFactory.beanDefinitionNames }")
	private List<String> beanDefinitionNames;

	/**
	 *	3)实例方法调用
	 */
	@Value("#{ 'zxd'.length() }")
	private int length;

	/**
	 *	4)关系操作符
	 */
	@Value("#{ 2>=1 }")
	private boolean operator;
	@Value("#{ true or false}")
	private boolean or;
	@Value("#{ true and false}")
	private boolean and;
	@Value("#{ !true }")
	private boolean not;
	@Value("#{ (1+2)*3/4-5 }")
	private int plus;
	@Value("#{ 7%3 }")
	private int mod;

	/**
	 *	5)静态属性
	 */
	@Value("#{ T(java.lang.Math).PI }")
	private double pi;

	/**
	 * 6)构造函数
	 */
	@Value("#{ new org.zxd.spring5.springmvc.controller.User('zxd',29)}")
	private User user;

	/**
	 *	7)静态方法调用
	 */
	@Value("#{ T(org.zxd.spring5.springmvc.controller.User).of('prince',28) }")
	private User staticUser;

	/**
	 *	8)#root 永远表示根对象
	 */
	@Value("#{ #root }")
	private BeanExpressionContext beanExpressionContext;

	/**
	 *	9)#this 永远表示当前评估的对象
	 */
	@Value("#{ {1,3,5,7}.?[#this>2] }")
	private List<Integer> gt2;

	/**
     *  10)使用 beanResolver 读取名称为 spELController 的 bean
     *  使用 @ 读取实例 bean,使用 & 读取工厂 bean
     */
	@Value("#{ @jacksonObjectMapper }")
	private ObjectMapper objectMapper;

	/**
	 *	11)三元操作符
	 */
	@Value("#{ true?'trueExpr':'falseExpr' }")
	private String expr;

	/**
	 *	12)埃维尔斯操作符
	 */
	@Value("#{ null?:'defaultValue' }")
	private String unkonwn;

	/**
	 *	13)安全导航操作符
	 */
	@Value("#{ null?.field }")
	private String safeNull;

	/**
	 *	14)集合选择
	 *	.?[]	从集合中筛选元素,返回一个新的集合
	 *	.^[]	获取第一个匹配的元素
	 *	.$[]	获取最后一个匹配的元素
	 */
	@Value("#{ {'java','maven','hello'}.^[#this.length()==5] }")
	private String firstMatch;
	@Value("#{ {'java','maven','hello'}.$[#this.length()==5] }")
	private String lastMatch;

	/**
	 *	15)集合投影
	 */
	@Value("#{ {'java','maven','hello'}.![#this.length()] }")
	private List<Integer> projection;

	/**
	 *	16)表达式模板
	 */
	@Value("random number is #{ T(java.lang.Math).random() }")
	private String template;

	@GetMapping("/validate")
	public void validate() {
		assertEquals("zxd", name);
		assertEquals(29, age);
		assertTrue(male);
		assertEquals(15505883728L, phone);
		assertNotNull(beanDefinitionNames);
		assertEquals(3, length);
		assertTrue(operator);
		assertTrue(or);
		assertFalse(and);
		assertFalse(not);
		assertEquals(-3, plus);
		assertEquals(1, mod);
		assertEquals(Math.PI, pi, 0);
		assertEquals("zxd", user.getName());
		assertEquals(29, user.getAge());
		assertEquals("prince", staticUser.getName());
		assertEquals(28, staticUser.getAge());
		assertNotNull(beanExpressionContext);
		assertTrue(CollectionUtils.isEqualCollection(Lists.newArrayList(3, 5, 7), gt2));
		assertNotNull(objectMapper);
		assertEquals("trueExpr", expr);
		assertEquals("defaultValue", unkonwn);
		assertNull(safeNull);
		assertEquals("maven", firstMatch);
		assertEquals("hello", lastMatch);
		assertTrue(CollectionUtils.isEqualCollection(Lists.newArrayList(4, 5, 5), projection));
	}

	/**
	 *	查看容器中注册的所有 bean及其类型
	 */
	@Autowired
	private AnnotationConfigServletWebServerApplicationContext applicationContext;
	@Override
	public void run(ApplicationArguments args) throws Exception {
		log.info("applicationContext {}", applicationContext.getClass());
		Stream.of(applicationContext.getBeanDefinitionNames()).forEach(name -> {
			log.info("{}==={}", name, applicationContext.getBean(name).getClass());
		});
	}
}
  • 自定义解析
public class SpelEvaluate {

    @Test
    public void evaluate() {
        // SpelExpressionParser 是线程安全的,可复用
        final SpelExpressionParser spelExpressionParser = new SpelExpressionParser();
        final String expressionString = "#{name}";
        final ParserContext context = ParserContext.TEMPLATE_EXPRESSION;
        final Expression rootExpress = spelExpressionParser.parseExpression(expressionString, context);

        final User user = User.of("zxd", 29);
        final StandardEvaluationContext evaluationContext = new StandardEvaluationContext(user);
        // 基于 evaluationContext 的 root 执行计算
        final String name = rootExpress.getValue(evaluationContext, String.class);
        // 基于自定义 root 执行计算
        final String fromRoot = rootExpress.getValue(user, String.class);
        assertEquals(name, fromRoot);

        /**
         *  直接以 # 开头的表达式表示从变量映射中读取,而不是从根开始解析
         *  #root 表示根对象,#this 表示当前解析对象【适用于集合操作】
         */
        final Expression rootName = spelExpressionParser.parseExpression("#root.name");
        final String root = rootName.getValue(evaluationContext, String.class);

        evaluationContext.setVariable("zxd", user);
        final Expression variableName = spelExpressionParser.parseExpression("#zxd.name");
        final String variable = variableName.getValue(evaluationContext, String.class);
        assertEquals(root, variable);
    }

    @Value(staticConstructor = "of")
    private static class User {
        private String name;
        private int age;
    }

}

posted on 2019-01-20 15:30  竺旭东  阅读(402)  评论(0编辑  收藏  举报

导航