【问题标题】:Save method is intercepted but findAll is notSave 方法被拦截但 findAll 没有
【发布时间】:2020-03-29 12:24:42
【问题描述】:

问题很简单

@Around("execution(* package.*Repository.save(..))")
public Object saveInterupt(ProceedingJoinPoint joinPoint) throws Throwable {
// This gets called whenever repository save is called
}

@Around("execution(* package.*Repository.findAll(..))")
public Object findInterupt(ProceedingJoinPoint joinPoint) throws Throwable {
// This IS NOT GETTING called whenever repository findAll is called
}

在这里打破头颅!

编辑:一个小的突破。我打印了目标,它返回 SimpleJpaRepository 而不是实际存储库。

【问题讨论】:

  • 简单的问题,调试一天没解决。头疼!
  • CrudRepository 中的方法findAll 和save 在SimpleJpaRepository 中默认实现。所以*Repository是一个jdk动态代理,在运行时为了纪念SimpleJpaRepository。
  • @Lebecca 那么我如何记录实际的调用类?
  • 您可以在SimpleJpaRepository save() or getAll() 方法中设置一个断点,并在调试模式下运行应用程序来证明我的话。关键不是内部对象,而是代理在调用内部对象方法之前执行的调用链。 Spring 使用一些缓存来构建链,这对我来说很神秘,为什么 findAll 没有得到增强。
  • @Around("execution(* org..*Repository.save(..)) 和 @Around("execution(* org..*Repository.findAll(..)) 为我工作一直以来。如果您想在包级别进行拦截,可以组合 && 执行中的切入点指示符。

标签: java spring-boot spring-data-jpa spring-aop


【解决方案1】:

假设存储库具有以下构造

public interface JpaEmployeeRepository extends CrudRepository<JpaEmployee, Long> {..}

以下切入点适用于这两种情况

@Around("execution(* org..*Repository.save(..))")

和

@Around("execution(* org..*Repository.findAll(..))")

如果我正确理解了这个问题,则要求拦截特定包中特定方法的执行。如果是,可以在此处阅读有关相同内容的更多详细信息。 @AspectJ pointcut for all methods inside package

【讨论】:

    【解决方案2】:

    您使用的是 Spring-BOOT 吗? Spring-BOOT 中的 Aspecting 仅在第一次调用类中的单个方法时调用通知。如果您希望 Spring-BOOT 在任何给定类中的多个方法的所有情况下都尊重您的 @Around 建议——您需要将类作为 bean(SB 的 @Bean)访问......

    Spring-BOOT 的 AOP 与使用 AspectJ 的切面不是 100% 相同——主要区别在于 AspectJ 修改了 Spring 使用动态代理的字节码。

    【讨论】:

      猜你喜欢
      • 2021-05-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-23
      • 1970-01-01
      • 2011-03-15
      • 1970-01-01
      相关资源
      最近更新 更多