I am trying to create an Aspect which runs after every call to save() of Spring JpaRepository. I have defined my Aspect as follows:
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Aspect
@Component
@Slf4j
public class ProcessAspect {
@Autowired
private ProcessService processService;
@AfterReturning(value = "execution(* com.domain.control.repository.ProcessDao.save())))",
returning = "result")
private void propagateProcess(JoinPoint joinPoint, Object result) {
log.info("Aspect is working, congratulations. Jointpoint {} , result {}", joinPoint, result.toString());
Process process = (process) result;
// do something on the object returned by save()
processService.createOrUpdateProcess(process);
}
}
My repository is defined as follows:
@Repository
public interface ProcessDao extends JpaRepository<Process, String>
If I configure it this way then the aspect is not working.
How can I configure my aspect to run after generic JPA repository methods?
First your ProcessDao
doesn't have a save
method, so it won't match, secondly you have a pointcut with a no-args save
method and there is no such thing. Instead you want to use one of the Spring Data repository classes in your pointcut and match 1 argument.
Something like this
execution(* org.springframework.data.jpa.repository.JpaRepository+.save(..))))
or to make it more generic
execution(* org.springframework.data.repository.CrudRepository+.save(..))))
This should make your pointcut match. There is also a saveAll
and saveAndFlush
so you might want to add a few more pointcuts if you need to intercept those as well.