问题
I'm using Spring's CrudRepository
in combination with the annotation @RepositoryRestResource
to implement a simple CRUD-app that can be used throught a RESTful API. I now want to add an AspectJ pointcut on my repository, so that some functionalities will be executed whenever a CRUD-method from the interface is called.
First, I extend Spring's CrudRepository
to add some custom functionalities in my own interface:
@RepositoryRestResource(collectionResourceRel = "customers", path = "customers")
public interface CustomerRestRepository extends CrudRepository<Customer, Integer>{
Customer findOneByGuid(@Param("customerGuid") String customerGuid);
//Other custom methods.
}
Everything is working fine and I'm able to call this method via my REST client. I do not have to implement the interface CustomerRestRepository
since Spring is doing the job as a miracle in behind. This is one of the crucial advantages of extending Springs's CrudRepository
.
The problem, I'm facing now, is to add an AspectJ pointcut on this custom method findOneByGuid()
that will, for example, log every call of the method after it's execution.
What I've tried by so far is:
@Aspect
public aspect AfterCustomerCrudAspect {
@Pointcut(
"execution(* com.x.y.z.CustomerRestRepository.findOneByGuid(..))")
public void customerCrudMethod() {}
@AfterReturning("customerCrudMethod()")
public void doSomething() {
//Do something
}
}
I've also tried:
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)
...and many others I do not remember. All with the same frustrating result: The advice is never applied.
By the way, I do not face any exceptions and if I try execution(* *.*(..))
, the advice is working well - but, of course, not limited to the method findOneByGuid()
. Thus, I think my code is correct in general.
I know that it is not possible to set pointcuts on interfaces. But since I do not have to implement the interface CustomerRestRepository
by my own to get things working, I need to find a way to set a pointcut on an interface's method - or to find some other solution.
Well, one possible solution to that would be to implement the interface CustomerRestRepository
. But then I've to do all the implementation work for the repository by my own and skip using the advantages of Spring's CrudRepository
.
Thus, my question is, if there is a possibility to set a AspectJ pointcut on methods in a Spring CrudRepository
.
Many thanks in advance for all the answers.
回答1:
Well, I solved my problem in a different way.
Sometimes, things are less complicated than expected. Adding an AspectJ pointcut on a Spring CRUD-repository to execute some functionalities, whenever an entity is changed was not the best idea. (And at the best of my knowledge, it is not possible at all.)
There is a much more easier way to implement my requirement: The package javax.persistence
provides the annotation @EntityListeners
that suites perfectly to this job. So, annotate the entity class with the listener and implement the needed functionalities within the listener class:
@Entity
@EntityListeners(CustomerEntityListener.class)
//@Table, @NamedQueries and other stuff ...
public class Customer implements Serializable {
...
}
Implementation of the EntityListener
:
public class CustomerEntityListener {
@PostPersist
public void customerPostPersist(Customer customer) {
//Add functionalities
}
}
The EntityListener
also provides annotation for @PostUpdate
, @PostRemove
and so on - visit this site for more information.
来源:https://stackoverflow.com/questions/41922236/aspectj-pointcut-on-method-in-spring-crudrepository