需求:在切面逻辑中识别@Cache注解中的#name,并将#name识别为test3(String name, RegionPo po)方法中的name参数值
public class TestServiceImpl{
@Cache("#name")
@Override
public void test3(String name, RegionPo po) {
System.out.println("============正在执行===========");
}
}
首先定义一个annotation
package com.test.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Cache {
String value();
}
定义切面
package com.test.aspect;
import java.lang.reflect.Method;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.stereotype.Component;
import com.test.Cache;
@Component
@Aspect
public class CacheAspect {
@Around("@annotation(cache)")
public void doCache(ProceedingJoinPoint joinPoint, Cache cache) throws Throwable {
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
Object [] args = joinPoint.getArgs();
String result = parseExpression(cache.value(), method, args);
System.out.println("EL表达式解析结果:"+result);
//执行方法
joinPoint.proceed();
}
/**
* 解析
* @param expressionString
* @param method
* @param args
* @return
*/
private String parseExpression(String expressionString, Method method, Object[] args) {
//获取被拦截方法参数名列表
LocalVariableTableParameterNameDiscoverer discoverer = new LocalVariableTableParameterNameDiscoverer();
String[] paramNameArr = discoverer.getParameterNames(method);
//SPEL解析
ExpressionParser parser = new SpelExpressionParser();
StandardEvaluationContext context = new StandardEvaluationContext();
for (int i = 0; i < paramNameArr.length; i++) {
context.setVariable(paramNameArr[i], args[i]);
}
String result = parser.parseExpression(expressionString).getValue(context, String.class);
return result;
}
}
spring配置文件中加入
<context:component-scan base-package="com.test.aspect.**" />
<aop:aspectj-autoproxy/>
调用
RegionPo po = new RegionPo();
po.setId(12l);
po.setName("test");
regionService.test3("testName", po);
执行结果
已经成功取到值了
Spring EL表达式还支持拼接
@Cache("#name + #po.id")
@Override
public void test3(String name, RegionPo po) {
System.out.println("============正在执行===========");
}