模仿spring的CachePut等注解,因为CachePut等注解的限制,没法知足当前的需求,自定义了新注解并实现方式java
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 ""; }
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<arguments.length;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”spring
目前还不支持“#p0”的写法,研究中express