在放假之前就一直在解决这个问题,当时采用的方法的是利用拦截器对自定义的标签进行拦截。采用的是下边的方法。
Method method = invocation.getMethod();
MetaCacheable metaCacheable = method.getAnnotation(MetaCacheable.class);
String cacheName = KeyInfo.getFromMetaCacheable(metaCacheable).getValue();
String keys = KeyInfo.getFromMetaCacheable(metaCacheable).getKey();
但是这种方法存在一个问题,就是只能获取到自定义标签的内容而无法获取到方法中的参数。上边的例子中定义了一个MetaCache标签,通过MethodInvocation的实例获取到拦截到的方法的名字,进一步通过getAnnotation方法获取到标签的内容,下边是标签的定义
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface MetaCacheable {
String value();
String key() default "";
String keyGenerator() default "";
}
在sum(int a,int b)方法上添加的是MetaCahceable(key ="name",value="cacheName"),通过拦截器只能够获取到引号中的内容也就是name,而无法获取到方法中的a的值,这是一个很头疼的问题,因为在使用标签的时候通常需要获取到参数的值。但是拦截器好像无法做到,这我一个值得反思的地方,一直想用拦截器获取到方法中参数的值,但是查了各种资料也没有解决最终浪费了大量的时间。其实在一开始的时候就有建议去利用AOP做,而自己却一直坚持自己的想法。工程性的问题一方面是要有性能上的考虑,另一方法也得有时间上的考虑,很明显因为无谓的坚持导致了大量时间的浪费,这是一个教训。
下边看一下利用AOP来做这件事情,同样定义了上边l类似的Cacheable的标签,然后在切面上做这件事情。
MethodSignature signature = (MethodSignature) thisJoinPoint.getSignature();
Cacheable cacheable = signature.getMethod().getAnnotation(Cacheable.class);
String cacheName = cacheable.cacheName();
采用这种方法就可以获取到拦截器已经获取到的引号中的内容。
@Pointcut("execution(@Cacheable * *.*(..))")
@SuppressWarnings("unused")
private void cache() {
}
@Around("cache()")
public Object aroundCachedMethods(ProceedingJoinPoint thisJoinPoint)throws Throwable {
for (final Object arg : thisJoinPoint.getArgs()) {
//增加参数的类型和值
keyBuffer.append("arg");
}
}
采用上边的方法就能获取方法中的参数,这个标签中的参数和方法中的参数了。