如果满足以下条件,则需要创建一个与方法匹配的切入点的方面:
方面类看起来像这样
@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);
}
随着日食->警告:在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]
使用http://download.eclipse.org/tools/ajdt/35/update中的最后一个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 {}
和
package com.xxx.xxx.annotation;
// standard imports stripped
@Target(METHOD)
@Retention(RUNTIME)
@Documented
public @interface MyAnnotationForMethod {}
当然,它不能正常工作。
你能告诉我怎么了吗?
谢谢。
更新:
好的,我可以在此页面上找到最佳参考:注释,切入点和建议。
您可以匹配方法,但是将无法捕获参数(仅方法和注释)。因此,您将要做的是切入点匹配和反射的结合。像这样:
@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));
}
这是我针对上述方面的测试课程:
public class TestClass{
@MyAnnotationForMethod
public void simpleTestMethod(@MyAnnotationForParam final String param1){
System.out.println("Method body (simple)");
};
@MyAnnotationForMethod
public void complexTestMethod(final String param1,
@MyAnnotationForParam final Float param2,
@MyAnnotationForParam final Boolean param3){
System.out.println("Method body (complex)");
};
public static void main(final String[] args){
System.out.println("Starting up");
final TestClass testObject = new TestClass();
testObject.simpleTestMethod("Hey");
testObject.complexTestMethod("Hey", 123.4f, false);
System.out.println("Finished");
}
}
这是输出:
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
您可能会想缓存很多,而无需在每次执行中解析每个批注的每个参数。保留哪个方法的哪个参数带有注释的映射,并仅处理那些参数。
假设我有一个注释,如下所示: 然后在Aspect中,我怎么可能想写两个切入点,一个用于所有用@DB操作(isRead操作=true)注释的方法,一个用于@DB操作(isRead操作=false)?
我试图围绕使用自定义注释注释的方法定义一个切入点。注释有一个参数,我想在切入点定义中包含一个检查。 这是注释: 如何应用注释的示例: 现在我想有两个切入点定义,根据注释的内容选择这两种方法。 在注释本身上创建切入点相对容易: 这将匹配@MyAnno的每次出现。但是我如何定义两个切入点,一个将与包含的匹配,另一个将与包含的匹配
我想使用ElementType运行一个方面。参数注释,但它不起作用。从不调用about-tokenize方法。
假设我有这样一种方法: 是否有一个切入点表达式可以选择所有参数带有@CustomAnnotation注释的方法?如果是这样的话,有没有一种方法可以让我访问“value”参数?
AspectJ1.6版本
我有一个使用< code>Process注释定义的流程。此批注具有名为< code>name的属性。流程中包含任务。这些任务是用另一个名为< code>Task的注释定义的。此批注具有属性< code>processName。我有一个将< code>name作为泛型的泛型流程。此流程的任务是任务1、任务2和任务3,这三个任务都将< code>processName作为通用任务。我可以使用aspec