luca
luca

Reputation: 3318

Spring AOP @Before advice return value

I'm new with Spring AOP and I was wondering if it is possible to return a value from @Before to method and use this variable inside it, for example:

@Before("@annotation(CheckUserReservationPermission) && args(username,idReservation)")
public Reservation userCreationAdvice(ProceedingJoinPoint pjp, String username, Integer idReservation) throws Throwable {
    Reservation reservation = reservationServices.findById(idReservation);
    if (!reservation.getUser().getUsername().equals(username))
        throw new PermissionException("You can't delete the reservation with id: " + idReservation);
    return reservation;
}

and my method:

@Override
@CheckUserReservationPermission
public void deleteReservationById(String username, Integer idReservation) throws QueryException {
    synchronized(ReservationsSchedulerServicesImpl.class){
        databaseReservationServices.deleteReservationById(username, reservation);  
    }
}

Is there a way to make this? Otherwise I have to repeat the query. Thanks

UPDATE: With @Around I may have this code, but how can I retrieve the variable into deleteReservationById method?

@Around("@annotation(CheckUserReservationPermission) && args(username,idReservation)")
public Object userCreationAdvice(ProceedingJoinPoint pjp, String username, Integer idReservation) throws Throwable {
    Reservation reservation = reservationServices.findById(idReservation);
    if (!reservation.getUser().getUsername().equals(username))
        throw new PermissionException("You can't delete the reservation with id: " + idReservation);
    return pjp.proceed(new Object[] {reservation});
}

Upvotes: 1

Views: 7491

Answers (1)

Tnadev
Tnadev

Reputation: 10082

Edit 2:

  1. Advice

    @Around("@annotation(CheckUserReservationPermission) && args(username,idReservation)")
    public Object userCreationAdvice(ProceedingJoinPoint pjp, DeleteByIdRequest req) throws Throwable {
        Reservation reservation = reservationServices.findById(idReservation);
        if (!reservation.getUser().getUsername().equals(username)) {
            throw new PermissionException("You can't delete the reservation with id: " + idReservation);}
    
         req.setReservation(reservation);  
        return pjp.proceed(new Object[] {req});
    

    }

2. New Request POJO

 class DeleteByIdRequest {
      Reservation reservation;
      String username;
      Integer idReservation;
    }

3.Target Method

@Override
@CheckUserReservationPermission
public void deleteReservationById(DeleteByIdRequest request) throws QueryException {
    synchronized(ReservationsSchedulerServicesImpl.class){
        databaseReservationServices.deleteReservationById(username, reservation);  
    }
}

See the interfaces of this advices,

check what they return.

1.ThrowsAdvice

public void afterThrowing(IllegalArgumentException e) throws Throwable {
}

2.AfterReturningAdvice

public void afterReturning(Object returnValue, Method method,
        Object[] args, Object target) throws Throwable {
}

3.MethodBeforeAdvice

public void before(Method method, Object[] args, Object target)
        throws Throwable {

}

4.MethodInterceptor (Around Advice)

public Object invoke(MethodInvocation methodInvocation) throws Throwable {

}

If you note in 4th point only Around advice is returning object.

you have to define the joinPoint.proceed() to control when should the interceptor return the control to the original method.

Check simple example here

EDIT: I think this can be achieved with help of proceeding with arguments
Basically you can then call proceed() with the new arguments.

Upvotes: 1

Related Questions