在使用Aspectj调用joinPoint.getArgs时,如何使用javax注释忽略参数?

在使用Aspectj调用joinPoint.getArgs时,如何使用javax注释忽略参数?,java,post,annotations,aspectj,javax,Java,Post,Annotations,Aspectj,Javax,我的函数包括不同的javax查询注释,如:@QueryParam、@Context、@PathParam等 调用joinPoint.getArgs()时是否有排除这些参数的方法 例如: @POST @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON) @Path("{pathParam}/v1/{pathParam2}/") @MyAnnotation

我的函数包括不同的javax查询注释,如:
@QueryParam
@Context
@PathParam

调用joinPoint.getArgs()时是否有排除这些参数的方法

例如:

    @POST
    @Produces(MediaType.APPLICATION_JSON)
    @Consumes(MediaType.APPLICATION_JSON)
    @Path("{pathParam}/v1/{pathParam2}/")
    @MyAnnotation
    public Response update(@PathParam("pathParam") String p1, @PathParam("pathParam2") int p2, MyObject x);



    @Before("@annotation(MyAnnotation)")
        public void doSomething(JoinPoint joinPoint){
            Object[] objects = joinPoint.getArgs(); // HERE - is there a way to get only MyObject and not other params..?
    }

我想这样做的原因是我有几个URL,同时将~10%标记为持久性。这意味着我希望将输入数据保存在某个持久服务中。查询和上下文参数对我来说并不重要,但输入数据本身很重要。

我认为没有什么神奇的方法可以做到这一点,所以请使用显而易见的方法:

  • 定义你的论点接受标准
  • 根据先前定义的条件迭代参数和过滤器,就这样
您的验收标准似乎是arg没有使用这些javax注释进行注释,对吗

试试这个:

Object[] args = joinPoint.getArgs();
Annotation[][] anns = ((MethodSignature) joinPoint.getSignature()).getMethod().getParameterAnnotations();

for (int i = 0; i < args.length; i++) {
    for (int j = 0; j < args[i].length; j++) {
        // check here for the annotations you would like to exclude
    }
}
Object[]args=joinPoint.getArgs();
注释[][]anns=((MethodSignature)joinPoint.getSignature()).getMethod().getParameterAnnotations();
对于(int i=0;i
假设您真的使用了完整AspectJ,而不是像其他许多人一样使用Spring AOP,那么您应该知道,在完整AspectJ
@annotation(XY)
中,可能不仅匹配
执行()
连接点,还匹配
调用()
,即您的建议将被触发两次。更糟糕的是,如果方法执行之外的其他地方也被注释了——例如类、字段、构造函数、参数——切入点也将匹配,并且您尝试强制转换到
MethodSignature
将导致异常

此外,请注意,在@AspectJ语法中,您需要提供要匹配的注释的完全限定类名,也就是说,不要忘了在包名之前加上前缀。否则就没有对手了。因此,在执行任何其他操作之前,您希望将切入点更改为:

@注释(de.scrum_master.app.MyAnnotation)和执行(**(..)
下面是一个完全自洽的例子,一个产生可重复结果的例子,正如我在你问题下的评论中所要求的:

注释:

package de.scrum\u master.app;
导入java.lang.annotation.Retention;
导入java.lang.annotation.RetentionPolicy;
@保留(RetentionPolicy.RUNTIME)
public@interface MyAnnotation{}
驱动程序应用程序:

如您所见,测试方法的参数具有不同类型的注释:

  • 只有javax注释
  • javax+own注释
  • 只有你自己的注解
  • 无注释
  • 我们希望忽略1/2,只打印3/4

    package de.scrum\u master.app;
    导入javax.ws.rs.PathParam;
    导入javax.ws.rs.core.Response;
    公共类应用程序{
    公共静态void main(字符串[]args){
    新应用程序()更新(“foo”,11,“bar”,22);
    }
    @MyAnnotation
    公众回应更新(
    @PathParam(“PathParam”)字符串p1,
    @PathParam(“pathParam2”)@MyAnnotation int p2,
    @MyAnnotation字符串文本,
    整数
    ) {
    返回null;
    }
    }
    
    方面:

    正如用户Andre Paschoal开始在他的代码片段中显示的那样,您需要迭代参数和注释数组,以完成过滤技巧。我认为这很难看,可能只是为了日志记录(我假设这就是您想要做的),速度很慢,但出于价值考虑,以下是您的解决方案:

    package de.scrum\u master.aspect;
    导入java.lang.annotation.annotation;
    导入org.aspectj.lang.JoinPoint;
    导入org.aspectj.lang.annotation.Aspect;
    导入org.aspectj.lang.annotation.Before;
    导入org.aspectj.lang.reflect.MethodSignature;
    @面貌
    公共类参数FilterSpect{
    @在(@annotation(de.scrum_master.app.MyAnnotation)和&execution(**(..)之前)
    公共无效剂量测定(JoinPoint JoinPoint){
    对象[]args=joinPoint.getArgs();
    MethodSignature MethodSignature=(MethodSignature)joinPoint.getSignature();
    注释[][]annotationMatrix=methodSignature.getMethod().getParameterAnnotations();
    对于(int i=0;i
    控制台日志:

    条
    22
    

    塔达!:-)

    这段代码对我很有用:

    Annotation[][] anns = ((MethodSignature)   thisJoinPoint.getSignature()).getMethod().getParameterAnnotations();
    
    parameterValues = thisJoinPoint.getArgs();
    signature = (MethodSignature) thisJoinPoint.getSignature();
    parameterNames = signature.getParameterNames();
    if (parameterValues != null) {
        for (int i = 0; i < parameterValues.length; i++) {
    
            boolean shouldBeExcluded = false;
            for (Annotation annotation : anns[i]) {
                if (annotation instanceof ExcludeFromCustomLogging) {//<<---------ExcludeFromCustomLogging is my class
                    shouldBeExcluded = true;
                    break;
                }
            }
            if (shouldBeExcluded) {
                //System.out.println("should be excluded===>"+parameterNames[i]);
                continue;
            }
    
      //.......and your business
    
    }
    
    Annotation[]anns=((MethodSignature)thisJoinPoint.getSignature()).getMethod().getParameterAnnotations();
    parameterValues=thisJoinPoint.getArgs();
    signature=(MethodSignature)thisJoinPoint.getSignature();
    parameterNames=signature.getParameterNames();
    if(参数值!=null){
    对于(int i=0;iif(ExcludeFromCustomLogging的注释实例){//请描述您想要实现的目标,而不是您认为应该如何实现。然后,我非常乐观地认为我可以帮助您。您犯的错误与许多没有经验甚至有经验的开发人员一样:您头脑中有一个技术解决方案,而不是需求,因此不再有足够的开放性来考虑替代方案为了实现你想要的。展示更多的示例代码,解释在你的情况下会发生什么,以及你希望发生什么。我想你是对的,我现在就编辑这个问题。谢谢你这个问题仍然只包括