Home > Software design >  Is there any way to execute async method after the execution of spring controller?
Is there any way to execute async method after the execution of spring controller?

Time:01-12

  • I have this application where the controller is called and it does some database operations and commit them after the end of controller cycle of spring
  • Also in this controller itself we raise one async event which requires the data that we are persisting in the database while execution of controller.
  • Since the data is not persisted yet in db we cannot access it in our async event while the controller is still executing.

    What I want is, execution of this async event should start after the execution of controller itself is it possible to do so in spring?

CodePudding user response:

Use the annotation @TransactionalEventListener(phase = TransactionPhase.AFTER_COMPLETION) to define an event listener that fires after the completion of the transaction in the database:

@Component
public class TransactionEventListener {
    @TransactionalEventListener(phase = TransactionPhase.AFTER_COMPLETION)
    public void afterCompletion(PayloadApplicationEvent<EventData> event) {
        System.out.println("Event data: "   event.getPayload().data);
    }
}

Publish the event after saving the data using ApplicationEventPublisher. Note the method must be annotated with @Transactional because the transaction is required to fire the event.

@Autowired
private DataRepo dataRepo;

@Autowired
private ApplicationEventPublisher publisher;

 @Async
 @Transactional
 public void storeData() {
   ...
  dataRepo.save(data);
  publisher.publishEvent(eventData);
   ...
 }

CodePudding user response:

you can use spring aop to do this. If you're using spring boot, you can add @EnableAspectJAutoProxy to one of your configuration class, then create a aspect for your controller method:

@Aspect
@Component
public class SomeAspect {
    @Pointcut("execution(* org.demo..controller.SomeController.someMethod(..))")
    private void someMethodJointcut(){}

    @After("someMethodJointcut()")
    public void doAfter(JoinPoint joinPoint) {
        //use joinPoint.getArgs() get parameters that passed to the controller
        //call your async method here
    }

}

Use around advice if you need to access the execution result of the controller call.

  •  Tags:  
  • Related