在我的应用程序中,我有一些方法,其参数由一些注释注释。现在我想编写Aspect,使用注释属性中的信息对注释参数进行一些预处理。例如,方法:
public void doStuff(Object arg1, @SomeAnnotation CustomObject arg1, Object arg2){...}
方面:
@Before(...)
public void doPreprocessing(SomeAnnotation annotation, CustomObject customObject){...}
@Before应该写什么?
修改
感谢大家。有我的解决方案:
@Before("execution(public * *(.., @SomeAnnotation (*), ..))")
public void checkRequiredRequestBody(JoinPoint joinPoint) {
MethodSignature methodSig = (MethodSignature) joinPoint.getSignature();
Annotation[][] annotations = methodSig.getMethod().getParameterAnnotations();
Object[] args = joinPoint.getArgs();
for (int i = 0; i < args.length; i++) {
for (Annotation annotation : annotations[i]) {
if (SomeAnnotation.class.isInstance(annotation)) {
//... preprocessing
}
}
}
}
答案 0 :(得分:2)
这是一个应该有效的例子。 (我没有测试它,但它应该工作)
@Before("execution(public * *(..))")
public void preprocessAnnotations(JoinPoint joinPoint) throws Throwable {
MethodSignature methodSig = (MethodSignature) joinPoint.getSignature();
Annotation[][] annotations = methodSig.getMethod().getParameterAnnotations();
if(annotations != null){
for(Annotation[] annotArr: annotations){
for(Annotation annot: annotArr){
if(annot instanceof Resource){
String nameOfResource = ((Resource)annot).name();
}
}
}
}
}
在这里,我添加了javax.annotation.Resource
的测试,以显示如何使用答案,但当然您应该将其替换为您需要处理的注释
答案 1 :(得分:1)
你会这样做:
@Before("execution(* com.foo.bar.*.doStuff(..)) && args(arg1, arg2)")
public void logSomething(JoinPoint jp, CustomObject arg1, Object arg2) throws Throwable {
MethodSignature methodSignature = (MethodSignature) jp.getSignature();
Class<?> clazz = methodSignature.getDeclaringType();
Method method = clazz.getDeclaredMethod(methodSignature.getName(), methodSignature.getParameterTypes());
SomeAnnotation argumentAnnotation;
for (Annotation ann : method.getParameterAnnotations()[0]) {
if(SomeAnnotation.class.isInstance(ann)) {
argumentAnnotation = (SomeAnnotation) ann;
System.out.println(argumentAnnotation.value());
}
}
}
这是参数类型自定义注释:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.PARAMETER)
public @interface SomeAnnotation {
String value();
}
要拦截的方法:
public void doStuff(@SomeAnnotation("xyz") CustomObject arg1, Object arg2) {
System.out.println("do Stuff!");
}
你不能像
那样做@Before(...)
public void doPreprocessing(SomeAnnotation annotation, CustomObject customObject){...}
因为注释不是参数,在那里你只能引用参数。
您可以使用@args(annot)
完成自己的工作,但这只匹配放在参数类型本身上的注释,而不是实际参数前面的注释。 @args(annot)
适用于以下情况:
@SomeAnnotation
public class CustomObject {
}