天天看点

利用AOP获取自定义标签的参数以及方法的参数

在放假之前就一直在解决这个问题,当时采用的方法的是利用拦截器对自定义的标签进行拦截。采用的是下边的方法。

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");
	}
}
           

采用上边的方法就能获取方法中的参数,这个标签中的参数和方法中的参数了。