当前位置: 首页 > 知识库问答 >
问题:

如何忽略参数与javax注解时调用joinPoint.getArgs使用?

狄新翰
2023-03-14

我的函数包括不同的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%标记为持久性。这意味着我希望将输入数据保存在某个持久服务中。查询

共有3个答案

穆飞龙
2023-03-14

这个代码片段适合我:

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

}
许照
2023-03-14

我不认为有什么神奇的方法可以做到这一点,所以顺其自然:

  • 定义您的论点接受标准;
  • 根据之前定义的标准迭代args和过滤器,仅此而已。

看来你的接受标准是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
    }
}
高运诚
2023-03-14

假设您真的像许多其他人一样使用完整的AeyJ而不是Spring AOP,您应该意识到这样一个事实,即在完整的AeyJ@注解(XY)中,不仅可能匹配执行()连接点,还可能匹配调用(),即您的建议将被触发两次。更糟糕的是,如果方法执行以外的其他地方也被注释——例如类、字段、构造函数、参数——切入点也将匹配,您尝试转换为omeodSignature将导致异常。

此外,请注意,在@AspectJ语法中,您需要提供要匹配的注释的完全限定类名,即不要忘记在包名之前加上前缀。否则根本没有对手。因此,在做任何其他事情之前,您希望将切入点更改为:

@annotation(de.scrum_master.app.MyAnnotation) && execution(* *(..))

现在这里是一个完全自洽的例子,一个产生可重复结果的SSCCE,正如我在您的问题下的评论中所要求的那样:

注释:

package de.scrum_master.app;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {}

驱动程序应用程序:

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

  1. 仅javax注释

我们希望忽略#1/2,只打印#3/4。

package de.scrum_master.app;

import javax.ws.rs.PathParam;
import javax.ws.rs.core.Response;

public class Application {
  public static void main(String[] args) {
    new Application().update("foo", 11, "bar", 22);
  }

  @MyAnnotation
  public Response update(
    @PathParam("pathParam") String p1,
    @PathParam("pathParam2") @MyAnnotation int p2,
    @MyAnnotation String text,
    int number
  ) {
    return null;
  }
}

方面:

正如用户Andre Paschoal开始在他的代码片段中显示的那样,您需要迭代参数和注释数组,以实现过滤技巧。我认为这是相当丑陋的,可能只是为了日志记录(我想这就是你想要做的),但为了它的价值,这里是你的解决方案:

package de.scrum_master.aspect;

import java.lang.annotation.Annotation;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.reflect.MethodSignature;

@Aspect
public class ParameterFilterAspect {
  @Before("@annotation(de.scrum_master.app.MyAnnotation) && execution(* *(..))")
  public void doSomething(JoinPoint joinPoint) {
    Object[] args = joinPoint.getArgs();
    MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
    Annotation[][] annotationMatrix = methodSignature.getMethod().getParameterAnnotations();
    for (int i = 0; i < args.length; i++) {
      boolean hasJavaxAnnotation = false;
      for (Annotation annotation : annotationMatrix[i]) {
        if (annotation.annotationType().getPackage().getName().startsWith("javax.")) {
          hasJavaxAnnotation = true;
          break;
        }
      }
      if (!hasJavaxAnnotation)
        System.out.println(args[i]);
    }
  }
}

控制台日志:

bar
22

塔达!:-)

 类似资料:
  • 我有一个带有Jackson注释的POJO 因此,当Jackson库被其他框架(如RestEasy)用于自动编组时,这些注释有助于指导序列化和反序列化过程。

  • 我在我的应用程序中使用带有陶土的ehcache。当我使用带有陶土的ehcache时,我的响应时间增加了700倍。我认为陶土需要时间来测量物体的大小,因为它给了我警告: net.sf.ehcache.pool.sizeof。ObjectGraphWalker checkMaxDepth警告:在尝试计算对象图的大小时,已达到1000个对象引用的配置限制。如果继续调整大小操作,可能会出现严重的性能下降。

  • 我正在我的一个应用程序中使用新的android导航框架。应用程序的目的是充当启动器。 有时,当我尝试更改片段(使用navcontroller导航)时,它不会更改片段,而是记录下来 我知道之前有人问过这个问题,忽略navigate()调用:FragmentManager已经保存了它的状态,但没有解决方案。 我使用以下代码导航: Navigation.findNavController(视图)。id.

  • 问题内容: 假设您具有以下pyspark DataFrame: 接下来的两个代码块应该做同样的事情-即,如果不是,则返回该列的大写。但是,第二种方法(使用)会产生错误。 方法1 :使用 方法2 :在内部使用 这给了我。为什么调用中的检查似乎被忽略了? 我知道我可以改变我要避免这种错误,但我想知道为什么它的发生。 完整回溯 : 问题答案: 您必须记住,Spark SQL(与RDD不同)不是您所看到的

  • 问题内容: 我正在编写此代码: 此代码忽略空行,但我也想忽略以#开头的行(注释)。 任何想法如何添加多个模式? 问题答案: 更改为 要么 如果您想在之前忽略空格。

  • 问题内容: 我正在尝试获取python的subprocess.call方法以通过列表(由字符串序列组成)接受一些args命令,如python文档中所建议。为了在将此行为放到我的实际脚本中之前对其进行探索,我打开了IPython,运行了一些涉及shell设置和args命令不同组合的命令,并得到以下行为: 似乎无论何时shell = True,输出似乎都与以下内容相同: 我很困惑;当我设置shell