Java使用SpEL

2020-09-10  本文已影响0人  neko_11

什么是SpEL

SpEL(Spring Expression Language),即Spring表达式语言。它与JSP2的EL表达式功能类似,可以在运行时查询和操作对象。与JSP2的EL相比,SpEL功能更加强大,它甚至支持方法调用和基本字符串模板函数。SpEL可以独立于Spring容器使用——只是当成简单的表达式语言来使用;也可以在Annotation或XML配置中使用SpEL,这样可以充分利用SpEL简化Spring的Bean配置。

为什么使用SpEL

自定义注解的属性声明,一般只能使用字符串,但是如果需要使用方法的入参作为注解的值,我们就需要使用SpEL表达式。当然要实现这种目的还有很多方法,只是使用SpEL是最简单和灵活的。

自定义注解

这里定义一个用于方法的注解

@Target(value = {ElementType.METHOD})
@Retention(value = RetentionPolicy.RUNTIME)
public @interface Demo {

    String name() default "";
}

注解的使用示例,SpEL表达式的语法,可以参考这个博客

@Demo(name = "#user.id")
public void test(User user) {
    System.out.println(user);
}

切面注解处理

@Aspect
@Component
public class DemoAspectHandler {

    private final ExpressionParser parser = new SpelExpressionParser();

    @Around(value = "@annotation(demo)")
    public Object around(ProceedingJoinPoint joinPoint, Demo demo) throws Throwable {
        Method method = getMethod(joinPoint);
        Object[] parameterValues = joinPoint.getArgs();
        // SpEL表达式的上下文
        EvaluationContext context = new StandardEvaluationContext();
        Parameter[] parameters = method.getParameters();
        for (int i = 0; i < parameters.length; i++) {
            // 方法的入参全部set进SpEL的上下文
            String name = parameters[i].getName();
            Object value = parameterValues[i];
            context.setVariable(name, value);
        }
        Object value = parser.parseExpression(demo.name()).getValue(context);
        if (value != null) {
            String userId =  value.toString();
            // 这里即可获取方法入参的用户Id
            System.out.println(userId);
        }
    }
}

    private Method getMethod(JoinPoint joinPoint) {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        if (method.getDeclaringClass().isInterface()) {
            try {
                method = joinPoint.getTarget().getClass().getDeclaredMethod(signature.getName(), method.getParameterTypes());
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return method;
    }
上一篇下一篇

猜你喜欢

热点阅读