Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/308.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java AspectJ不执行关于反射的建议_Java_Aop_Aspectj - Fatal编程技术网

Java AspectJ不执行关于反射的建议

Java AspectJ不执行关于反射的建议,java,aop,aspectj,Java,Aop,Aspectj,我有一门课: class MyClass { @MyAnnotation public void someMethod() { } } 在切入点的建议中,我基本上是提取注释所针对的“方法”。然后,根据某些配置,该方法被委托给它的许多处理程序之一 在这一点上,我必须指出,所有问题的根源是我不能在建议中真正执行joinPoint.continue()Method.invoke()某种程度上需要在该方法上执行,因为在并行线程中有另一个委托继续调用该方法,并且该委托的执行没有

我有一门课:

class MyClass {
    @MyAnnotation
    public void someMethod() {

    }
}
在切入点的建议中,我基本上是提取注释所针对的“方法”。然后,根据某些配置,该方法被委托给它的许多处理程序之一

在这一点上,我必须指出,所有问题的根源是我不能在建议中真正执行
joinPoint.continue()
Method.invoke()
某种程度上需要在该方法上执行,因为在并行线程中有另一个委托继续调用该方法,并且该委托的执行没有
ProceedingJoinPoint

问题是,每当我在
someMethod
上执行
Method.invoke()
时,通知都会再次运行(当然),因为它上面有注释。这会导致它一次又一次地运行

我需要找到以下两种方法之一:

  • 如果由reflections或Method.invoke调用,则不要运行建议(我真的认为这是不可能的)
  • 在通知中检测呼叫是否来自其中一名学员
  • 对于#2,我考虑设置一个标志或其他东西,但这不再保证线程安全

    有什么建议吗

    更清晰的代码示例:

    我有一个明确的方面:

    @Pointcut("execution(@com.rohanprabhu.annotation.Process * *(..)) "
            + "&& @annotation(process)")
    public void processPointcut(Process process) {
    }
    
    @Around("processPointcut(process)")
    public Object process(final ProceedingJoinPoint joinPoint, final Process process)
            throws Throwable {
        final Object callingObject = joinPoint.getThis();
        final Method method = ((MethodSignature)joinPoint.getSignature()).getMethod();
        final MethodContext methodContext = new MethodContext(callingObject, method);
    
        //The below mentioned delegate will be picked
        //depending on some validation performed on 'callingObject'
        Object retValue = delegate.process(methodContext, joinPoint.getArgs());
        return retValue;
    }
    
    一个委托看起来像这样:

    class SimpleDelegate extends Delegate {
        @Override
        public Object process(final MethodContext methodContext, final Object[] args) {
            // The problem is that following invoke call calls
            // the @Around aspect to run again, which calls the delegate again,
            // which causes execution of the next line, which causes the aspect to run
            // again and so on...
            methodContext.getMethod().invoke(
                methodContext.getCallingObject(),
                args
            );
        }
    }
    
    如果我能做这样的事情就太好了(我真的不认为有像
    这样的东西叫做byreflection

    @Pointcut("execution(@com.rohanprabhu.annotation.Process * *(..)) "
            + "&& @annotation(process)" + " && !calledByReflection")
    public void processPointcut(Process process) {
    }
    
    或者类似于:

    @Around("processPointcut(process)")
    public Object process(final ProceedingJoinPoint joinPoint, final Process process,
                   final boolean processAnnotation)
            throws Throwable {
        if(processAnnotation) {
            // Do the regular stuff
        }
    }
    
    我有办法为方面提供
    processAnnotation
    的值。我希望这能澄清我的问题。
    }

    我想我可以帮你。我对你的意思有一个有根据的猜测,但要仔细检查,请提供一个最小但完整的代码示例(Java+方面代码)这再现了问题行为。如果我在家,我可以自己玩,但在路上只有一台iPad,我需要更多的输入。嘿,非常感谢你提供的帮助。我添加了更多的代码示例,甚至是想象中的代码,以了解解决方案的外观(也许可以在我的脑海中瞥一眼)。再次感谢。您可以使用call()而不是execution()作为切入点(假设您不使用spring aop)。我认为这不适用于反射调用。非常感谢!!这完全有效。如果您将其发布为答案,我会将其标记为正确的答案。同时,请对评论进行投票:)(如果你还想贴一个答案,我很乐意将其标记为正确的解决方案)。再次非常感谢你。。。