什么是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;
}
网友评论