Spring CrudRepository中的方法AspectJ切入点

3
我正在使用Spring的CrudRepository和注解@RepositoryRestResource结合使用,实现一个简单的CRUD应用程序,可通过RESTful API使用。现在我想在我的存储库上添加AspectJ连接点,以便每当调用接口中的CRUD方法时执行某些功能。
首先,我扩展Spring的CrudRepository,在自己的接口中添加一些自定义功能:
@RepositoryRestResource(collectionResourceRel = "customers", path = "customers")
public interface CustomerRestRepository extends CrudRepository<Customer, Integer>{
   Customer findOneByGuid(@Param("customerGuid") String customerGuid);
   //Other custom methods.
}

一切都很正常,我能够通过我的REST客户端调用这个方法。我不需要实现接口CustomerRestRepository,因为Spring在幕后执行了奇迹般的工作。这是扩展Spring的CrudRepository的重要优点之一。
我现在面临的问题是,在这个自定义的findOneByGuid()方法上添加一个AspectJ切点,例如,在它执行后记录每次调用方法。
到目前为止,我尝试过的方法是:
@Aspect
public aspect AfterCustomerCrudAspect {
   @Pointcut(
        "execution(* com.x.y.z.CustomerRestRepository.findOneByGuid(..))")
   public void customerCrudMethod() {}

   @AfterReturning("customerCrudMethod()")
   public void doSomething() {
      //Do something
   }
}

我也尝试了以下方法:
1) execution(* com.x.y.z.CustomerRestRepository+.findOneByGuid(..))
2) execution(* org.springframework.data.repository.Repository+.*(..))
3) within(com.x.y.z.CustomerRestRepository)
4) annotation(RepositoryRestResource)

......还有许多我不记得的其他建议。但它们都带来了同样令人沮丧的结果:这些建议从未被应用。

顺便说一句,我没有遇到任何异常,如果我尝试execution(* *.*(..)),建议会正常工作——但是,当然,并不仅限于方法findOneByGuid()。因此,我认为我的代码总体上是正确的。

我知道不能在接口上设置切入点。但由于我不必自己实现接口CustomerRestRepository即可使事情正常工作,我需要找到一种方法在接口的方法上设置切入点或找到其他解决方案。

好吧,解决这个问题的一个可能的方法是实现接口CustomerRestRepository。但是然后我必须自己完成存储库的所有实现工作,并跳过使用Spring的CrudRepository的优势。

因此,我的问题是,是否有可能在Spring CrudRepository的方法上设置AspectJ切入点

非常感谢您提前提供的所有答案。


这是我所能想到的唯一一种情况,当使用Spring AOP而不是AspectJ更好时。Spring AOP应该很好地适配于Spring自己的代理基础设施中。 - Nándor Előd Fekete
1个回答

3

我用了一个不同的方法解决了我的问题。

有时候,事情并没有想象中那么复杂。在Spring CRUD-repository上添加AspectJ切入点来执行某些功能,每当实体被更改时,这不是最好的主意。(而据我所知,这根本不可能。)

有一个更加容易实现我的需求的方法:包javax.persistence提供了注释@EntityListeners,非常适合此工作。因此,在实体类上注释监听器并在监听器类中实现所需的功能:

@Entity
@EntityListeners(CustomerEntityListener.class)
//@Table, @NamedQueries and other stuff ...
public class Customer implements Serializable {
   ...
}

实现EntityListener

public class CustomerEntityListener {
   @PostPersist
   public void customerPostPersist(Customer customer) {
      //Add functionalities
   }
}

EntityListener还提供了@PostUpdate@PostRemove等注释 - 请访问此网站获取更多信息


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接