Java 带注释参数的切入点匹配方法
我需要创建一个切入点与方法匹配的方面,如果:Java 带注释参数的切入点匹配方法,java,parameters,annotations,aop,aspectj,Java,Parameters,Annotations,Aop,Aspectj,我需要创建一个切入点与方法匹配的方面,如果: 它是用MyAnnotationForMethod注释的 它的一个参数(可以有多个)用@MyAnnotationForParam注释(但也可以有其他注释) aspect类如下所示 @Pointcut("execution(@MyAnnotationForMethod * *(..,@aspects.MyAnnotationForParam Object, ..)) && args(obj)") void myPointcut(JoinP
@Pointcut("execution(@MyAnnotationForMethod * *(..,@aspects.MyAnnotationForParam Object, ..)) && args(obj)")
void myPointcut(JoinPoint thisJoinPoint, Object obj) {
}
@Before("myPointcut(thisJoinPoint , obj)")
public void doStuffOnParam(JoinPoint thisJoinPoint, Object obj) {
LOGGER.info("doStuffOnParam :"+obj);
}
注释法
@MyAnnotationForMethod
public string theMethod(String a, @MyAnnotationForParam @OtherAnnotation Object obj, Object b){
LOGGER.info(a+obj+b);
}
使用eclipse->warnings:在poincut上:
Multiple markers at this line
- no match for this type name: MyAnnotationForMethod [Xlint:invalidAbsoluteTypeName]
- no match for this type name: aspects.MyAnnotationForParam On the before : advice defined in xxx.xxx.xxx.xxx.MyAspect has not been applied [Xlint:adviceDidNotMatch]
使用来自的最后一个aspectJ插件
使用aspectj 1.6.9使用maven命令行
[WARNING] no match for this type name: MyAnnotationForMethod [Xlint:invalidAbsoluteTypeName]
[WARNING] no match for this type name: aspects.MyAnnotationForParam [Xlint:invalidAbsoluteTypeName]
[WARNING] advice defined in xxx.xxx.xxx.xxx.MyAspect has not been applied [Xlint:adviceDidNotMatch]
注释:
package com.xxx.xxx.annotation;
// standard imports stripped
@Documented
@Target( { FIELD, CONSTRUCTOR, PARAMETER })
@Retention(RUNTIME)
public @interface @MyAnnotationForParam {}
及
当然,它不能正常工作
你能告诉我怎么了吗
thx.更新: 好的,我能找到的最好的参考资料是在这页: 您可以匹配方法,但是无法捕获参数(仅捕获方法和注释)。所以你需要做的是切入点匹配和反射的结合。大概是这样的:
@Pointcut(
"execution(@com.xxx.xxx.annotation.MyAnnotationForMethod * *(.., @com.xxx.xxx.annotation.MyAnnotationForParam (*), ..))")
public void annotatedMethod(){}
@Before("annotatedMethod()")
public void doStuffOnParam(final JoinPoint jp){
final Signature signature = jp.getSignature();
if(signature instanceof MethodSignature){
final MethodSignature ms = (MethodSignature) signature;
final Method method = ms.getMethod();
final String[] parameterNames = ms.getParameterNames();
final Class<?>[] parameterTypes = ms.getParameterTypes();
final Annotation[][] parameterAnnotations =
method.getParameterAnnotations();
for(int i = 0; i < parameterAnnotations.length; i++){
final Annotation[] annotations = parameterAnnotations[i];
final MyAnnotationForParam paramAnnotation =
getAnnotationByType(annotations, MyAnnotationForParam.class);
if(paramAnnotation != null){
this.processParameter(ms.toShortString(),
parameterNames[i],
parameterTypes[i],
paramAnnotation);
}
}
}
}
/**
* In an array of annotations, find the annotation of the specified type, if any.
* @return the annotation if available, or null
*/
@SuppressWarnings("unchecked")
private static <T extends Annotation> T getAnnotationByType(final Annotation[] annotations,
final Class<T> clazz){
T result = null;
for(final Annotation annotation : annotations){
if(clazz.isAssignableFrom(annotation.getClass())){
result = (T) annotation;
break;
}
}
return result;
}
/**
* Do some processing based on what we found.
* @param signature method signature
* @param paramName parameter name
* @param paramType parameter type
* @param paramAnnotation annotation we found
*/
private void processParameter(final String signature,
final String paramName,
final Class<?> paramType,
final MyAnnotationForParam paramAnnotation){
System.out.println(MessageFormat.format(
"Found parameter ''{0}'' \n of type ''{1}'' \n with annotation ''{2}'' \n in method ''{3}''",
paramName,
paramType,
paramAnnotation,
signature));
}
以下是输出:
Starting up
Found parameter 'param1'
of type 'class java.lang.String'
with annotation '@com.xxx.xxx.annotation.MyAnnotationForParam()'
in method 'TestClass.simpleTestMethod(..)'
Method body (simple)
Found parameter 'param2'
of type 'class java.lang.Float'
with annotation '@com.xxx.xxx.annotation.MyAnnotationForParam()'
in method 'TestClass.complexTestMethod(..)'
Found parameter 'param3'
of type 'class java.lang.Boolean'
with annotation '@com.xxx.xxx.annotation.MyAnnotationForParam()'
in method 'TestClass.complexTestMethod(..)'
Method body (complex)
Finished
暗示
您可能需要缓存大量的数据,不需要在每次执行中解析每个注释的每个参数。保留带有注释的方法的哪个参数的映射,并仅处理这些参数。当从接口实现该方法时,上述解决方案中的ms.getParameterNames()调用似乎不起作用。我得到空值
但是,如果启用CGLIB,它就会工作
<aop:aspectj-autoproxy proxy-target-class="true"/>
您能否显示这两个批注的代码,包括它们的包声明。批注是否具有retention=RUNTIME?相关:Sean,您知道为什么需要自己定义的批注的完整类路径吗。这就是我在过去两个小时里一直在做的事。Thanks@Bill问题是aspectj通常在编译类上工作,而不是在源代码上。导入不存储在类中。因此,实际上没有办法从切入点批注中找到的类名中猜测限定名。@只有@SeanPatrickFloyd使用代理目标类也允许获取参数批注时,Nittin参数名才可用。在添加此设置之前,我总是得到空数组。
Starting up
Found parameter 'param1'
of type 'class java.lang.String'
with annotation '@com.xxx.xxx.annotation.MyAnnotationForParam()'
in method 'TestClass.simpleTestMethod(..)'
Method body (simple)
Found parameter 'param2'
of type 'class java.lang.Float'
with annotation '@com.xxx.xxx.annotation.MyAnnotationForParam()'
in method 'TestClass.complexTestMethod(..)'
Found parameter 'param3'
of type 'class java.lang.Boolean'
with annotation '@com.xxx.xxx.annotation.MyAnnotationForParam()'
in method 'TestClass.complexTestMethod(..)'
Method body (complex)
Finished
<aop:aspectj-autoproxy proxy-target-class="true"/>