【问题标题】:AOP advice called twice apart from first pointcut除了第一个切入点外,AOP 建议调用了两次
【发布时间】:2018-05-02 16:26:25
【问题描述】:

我在我的 Java Spring 应用程序中使用基于注解的 AOP。根本没有 XML 配置(除了 log4j2.xml)。

我的第一个切入点按预期执行一次,但之后的每个切入点都会执行两次,我不知道为什么。

这是我的配置类:

@Configuration @EnableAspectJAutoProxy
public class LoggingConfig
{
    @Bean public PreProcessLogs preProcessLogs(){
        return new PreProcessLogs();
    }
}

以及 Aspect 类:

@Aspect
public class PreProcessLogs
{
    @Before("execution(* <package>.preprocessor.services.DownloadService.addToDownloading(..)) " + "&& args(event)")
    public void LogFTPFile(JoinPoint joinPoint, WatchEvent<?> event) {
        Logger logger = (org.apache.logging.log4j.core.Logger) LogManager.getLogger(joinPoint.getSignature().getDeclaringTypeName());
        logger.log(Level.INFO, event.context().toString() + " has appeared in the FTP\n");
    }

    @AfterReturning("execution(void <package>.preprocessor.services.DownloadService.addToDownloaded(..)) " + "&& args(filePath)")
    public void logDownloadedFile(JoinPoint joinPoint, Path filePath) {
        //Logger logger = (org.apache.logging.log4j.core.Logger) LogManager.getLogger(joinPoint.getSignature().getDeclaringTypeName());
        //logger.log(Level.INFO, file.getFileName() + " has finished downloading");
        //System.out.println(joinPoint.getSourceLocation());
        System.out.println(filePath.getFileName() +" has been downloaded");
    }

    @After("execution(void <package>.preprocessor.services.FileTransferService.moveToStagingFolder(..)) " + "&& args(file)")
    public void logFileTransfer(JoinPoint jp, Path file) {
        System.out.println(file.getFileName() + " has been moved to the Staging Folder");
    }
}

所以基本上@AfterReturning 和@After 切入点被执行两次而不是一次。 @Before 注释按预期执行一次。我用底部的两个切入点尝试了@Before,但效果相同。我也尝试使用@Pointcut 定义切入点,但同样的事情发生了。我还尝试指定 (..)) 所在的类型。

在我试图让它发挥作用的束缚结束时,请有人将我推向正确的方向。

谢谢。

【问题讨论】:

  • 不,它们不会执行两次(除非有人也调用了两次),您只是认为它们会执行。但是没有目标代码是无法分析的。所以请提供一个MCVE,包括方面+应用程序代码,包括。类和包名。
  • 我投票结束这个问题,因为它缺少重现问题所必需的minimal reproducible example

标签: java spring aop aspectj pointcut


【解决方案1】:

Spring 不应多次处理方面。检查您是否在班级顶部有@component 或@service。如果是,请将它们删除并查看。还可以使用@EnableJAutoproxy。可能是创建了两个代理,因此方面执行了两次。此外,检查是否从该类的另一个同级方法调用了带注释的方法。这也可能有问题。

【讨论】:

  • 没有多余的@component 或@service,你可以在上面的代码中看到。如何使用@EnableJAutoProxy?我的代码中没有任何子类。
  • 加上第一个切入点按预期执行一次,但最后两个切入点执行两次。
  • 第二、第三个方法是从第一个调用的吗?检查如果您删除那些“兄弟”方法调用并从其他地方调用第二/第三方法会发生什么。你还会被处决 2 次吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-12-15
  • 1970-01-01
  • 2017-01-19
  • 1970-01-01
  • 2018-06-07
  • 2021-08-13
  • 1970-01-01
相关资源
最近更新 更多