模仿spring的CachePut等注解,由于CachePut等注解的限制,无法满足当前的需求,自定义了新注解并实现方式
编写注解
package com.example.providerserver.el;
import org.springframework.core.annotation.AliasFor;
import java.lang.annotation.*;
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface CacheTest {
@AliasFor("value")
String key() default "";
@AliasFor("key")
String value() default "";
}
编写AOP切面
package com.example.providerserver.el;
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.springframework.core.LocalVariableTableParameterNameDiscoverer;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.Expression;
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 java.lang.reflect.Method;
@Component
@Aspect
public class CacheAOP {
@Pointcut(value="@annotation(CacheTest)")
private void getPointcut() {
}
@Around("getPointcut()")
public Object preProcessQueryPattern(ProceedingJoinPoint point) throws Throwable {
String targetName = point.getTarget().getClass().getName();
String simpleName = point.getTarget().getClass().getSimpleName();
String methodName = point.getSignature().getName();
Object[] arguments = point.getArgs();
Class targetClass = Class.forName(targetName);
Method[] methods = targetClass.getMethods();
String key = "";
String[] paramNames = {};
for(Method method:methods){
if(method.getName().equals(methodName)){
key = method.getAnnotation(CacheTest.class).key();
System.out.println("key is "+key);
paramNames = getParamterNames(method);
}
}
ExpressionParser parser = new SpelExpressionParser();
Expression expression = parser.parseExpression(key);
EvaluationContext context = new StandardEvaluationContext();
for(int i=0;i
context.setVariable(paramNames[i],arguments[i]);
}
System.out.println(expression.getValue(context,String.class));
return point.proceed();
}
public String[] getParamterNames(Method method){
LocalVariableTableParameterNameDiscoverer u =
new LocalVariableTableParameterNameDiscoverer();
return u.getParameterNames(method);
}
// public static void main(String[] args) {
// LocalVariableTableParameterNameDiscoverer u =
// new LocalVariableTableParameterNameDiscoverer();
// Test test = new Test();
// Method[] methods = test.getClass().getMethods();
// for(Method method :methods){
// if(method.getName().equals("test")){
// System.out.println(u.getParameterNames(method).toString());
// }
// }
// }
}
测试
@CacheTest(key = "#result.name+'.nbper'")
public String hello(Result result){
return result.getName();
}
在调用hello方式中传入参数"hello" 最终将打印出 “hello.abc”
目前还不支持“#p0”的写法,研究中