javaspringaopspring-aop

How to pause/resume some Spring AOP pointcut


In a Spring application, we added some AOP pointcuts to do intercept save, saveAll, ... methods of jpa repositories to refresh a materilized view each time the entities are inserted, updated.

But, we have some batching processes that need to call thoses save methods a lot of time. (And no, it is not possible to make a unique saveAll at the end of the batch as the existing code is too complicated to refactor)

Is there a simple way to ask Spring to pause a specific AOP pointcut during the batch processing, and then resume it when needed?

// begining of the batch
// Spring my friend, please pause the AOP pointcut

for(...) {
  // do some logic
  myEntityRepository.save(myEntity);
}

// Ok, I'm done, Spring my friend, please resume the AOP pointcut
// end of the batch

Solution

  • I'm not sure if I've misunderstood, but if I have, please let me know.

    Are you trying to execute the save method multiple times in method A, but the save method is already listened to by AOP, so you want to execute the rest of the AOP process after all the save methods in method A are finished?

    Based on my understanding, my solution is shown below

    @Component
    public class BatchProcessingState {
        private final AtomicBoolean isBatchMode = new AtomicBoolean(false);
    
        public void enableBatchMode() {
            isBatchMode.set(true);
        }
    
        public void disableBatchMode() {
            isBatchMode.set(false);
        }
    
        public boolean isBatchMode() {
            return isBatchMode.get();
        }
    }
    
    @Autowired
    private BatchProcessingState batchProcessingState;
    
    @Around("xxx")
    public Object aroundSaveMethods(ProceedingJoinPoint joinPoint) throws Throwable {
        if (batchProcessingState.isBatchMode()) {
            return joinPoint.proceed();
        }
    
        System.out.println("Intercepts the save method and executes AOP logic...");
        Object result = joinPoint.proceed();
        System.out.println("The save method completes");
        return result;
    }
    
    public void processBatch() {
        // test entity list
        List<News> newsList = new ArrayList<>();
        for (int i = 0; i < 5; i++) {
            News tempNews = new News();
            tempNews.setTitle("this is a temp entity");
            newsList.add(tempNews);
        }
    
        // handle
        System.out.println("START, pause AOP");
        batchProcessingState.enableBatchMode();  // close AOP
    
        try {
            for (News news : newsList) {
                save(news);  // AOP logic does not trigger
            }
        } finally {
            batchProcessingState.disableBatchMode();  // resumption AOP
            System.out.println("FINISH, resumption AOP");
        }
    }
    

    Result:

    START, pause AOP
    
    (5 times the save method was executed)
    
    FINISH, resumption AOP