模仿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