Spring SpEL 表达式解析

1. Spring SpEL 表达式解析

实现类似 Spring Cache 中 @Cacheable(key="#userName") 效果,解析出注解中的 Spel 表达式。

1.1. 定义注解

package com.spel;

import java.lang.annotation.*;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface PersonName {
    String value();
}

1.2. 定义模型,使用自定义注解修饰方法

package com.spel;

import org.springframework.stereotype.Component;

@Component
public class Person {
    @PersonName("#name")
    public void sayHello(String name) {
        System.out.println("Hello!");
    }
}

1.3. 定义切面

package com.spel;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.context.expression.MethodBasedEvaluationContext;
import org.springframework.core.DefaultParameterNameDiscoverer;
import org.springframework.expression.Expression;
import org.springframework.expression.TypedValue;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

@Component
@Aspect
public class PersonNameAspect {
    private SpelExpressionParser spelExpressionParser = new SpelExpressionParser();

    @Pointcut("@annotation(com.spel.PersonName)")
    public void pointCut() {

    }

    @Around("pointCut()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        PersonName personName = method.getAnnotation(PersonName.class);
        String spel = personName.value();
        ParameterNameDiscoverer parameterNameDiscoverer = new DefaultParameterNameDiscoverer();
        EvaluationContext evaluationContext = new MethodBasedEvaluationContext(TypedValue.NULL, method, joinPoint.getArgs(), parameterNameDiscoverer);
        Expression expression = spelExpressionParser.parseExpression(spel);
        Object name = expression.getValue(evaluationContext);
        System.out.printf("%s says: \n", name);
        return joinPoint.proceed();
    }
}

1.4. 启动程序

package com.spel;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;

@SpringBootApplication
public class SpelDemo {
    public static void main(String[] args) {
        ApplicationContext context = SpringApplication.run(SpelDemo.class);
        Person person = context.getBean(Person.class);
        person.sayHello("Jack");
    }
}

结果打印:

Jack says: 
Hello!
posted @ 2024-09-03 16:55  Jason207010  阅读(117)  评论(0)    收藏  举报