关于Spring CrudRepository中方法的AspectJ切入点

时间:2017-01-29 14:55:33

标签: spring interface aspectj crud pointcut

我将Spring的CrudRepository与注释@RepositoryRestResource结合使用,以实现可以通过RESTful API使用的简单CRUD应用。我现在想在我的存储库中添加 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正在做后面的奇迹。这是扩展Springs 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切入点。

非常感谢所有答案。

1 个答案:

答案 0 :(得分:2)

好吧,我以不同的方式解决了我的问题。

有时,事情并不像预期那么复杂。在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提供了注释,依此类推 - visit this site for more information