I am working with:
Spring Framework4.3.3AspectJ1.8.9
I have the following normal process:
@Controller->@Service->@Repository
I have the following pair about AOP:
PersonaServicePointcutPersonaServiceAspect
The scenario is the following:
The @Service class has some methods such as: delete, save, update and findOneById. They are declared together within the same class.
For the methods such as delete and update through AOP I am using a @Before or @Around advice to call the findOneById method.
The reason is that does not make sense execute the delete or update methods (consider Rest scenario) if the entity does not exist. Therefore through that advice an exception must be throw, lets say Exception A, it must be handled in a @ControllerAdvice
Practically the same approach for the save method has been applied. Therefore before to execute the save method other @Before or @Around advice is executed calling the findOneById method again. If the entity already exists an exception must be thrown, lets say Exception B, it must be handled in a @ControllerAdvice
Observe I have 3 points/3advices that use the findOneById method. It to check if exists an entity or not.
For example:
@Pointcut(value=
"execution(* mypackage.PersonaServiceImpl.saveOne(otherpackage.Persona))
&& args(persona)")
public void saveOnePointcut(Persona persona){}
@Pointcut(value=
"execution(*
mypackage.PersonaServiceImpl.updateOne(otherpackage.Persona))
&& args(persona)")
public void updateOnePointcut(Persona persona){}
@Pointcut(value="execution(*
mypackage.PersonaServiceImpl.deleteOne(String)) && args(id)")
public void deleteOnePointcut(String id){}
Again: these 3 advices use or execute the findOneById method.
The problem is when I add a new pointcut such as:
@Pointcut(value="execution(*
mypackage.PersonaServiceImpl.findOneById(String))
&& args(id)")
public void findOneByIdPointcut(String id){}
I have created this pointcut to check if an entity already exists or not, if it does not exist it must throw an exception of type C (it for the classic 404).
Seems redundant execute the findOneById method through a @Before or @Around advice for the findOneById method itself. But I need this to logging and audit purposes and to create the exception of type C too. It must be handle by some @ControllerAdvice
The problem is when the others advices for the delete/update/save methods are executed (remember they call and execute the findOneById method too) my findOneByIdPointcut is executed unnecessarily.
I need change the pointcut declaration to indicate something like this:
@Pointcut(Alpha)
public void findOneByIdPointcut(String id){}
Where Alpha is:
execute the before/around advice for the @Service's findOneById method, but never if its call has been done from the others advices from the
PersonaServiceAspect class.
I've tried many ways with !execution and !within combinations, but no results.
Even when I have created just one Pointcut that intercepts all the @Service's methods with its respective unique @Around advice, and through the ProceedingJoinPoint proceedingJoinPoint parameter I am able to check what method has been called and then do the respective controls. But again this behaviour happens.
It means, through the following:
@Around("PersonaServicePointcut.anyMethodPointcut()")
public Object aroundAdviceAnyMethod(ProceedingJoinPoint proceedingJoinPoint) throws Throwable{
where anyMethodPointcut is execution(* mypackage.PersonaServiceImpl.*(..))
Is possible accomplish this approach? How?
Thanks.