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
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
Share
Improve this question
asked 19 hours ago
fluminisfluminis
4,0794 gold badges36 silver badges48 bronze badges
1 Answer
Reset to default 0I'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");
}
}
Rusult:
START, pause AOP
(5 times the save method was executed)
FINISH, resumption AOP