Issue
I want to start a daemon mail service thread on tomcat server startup. So, I have annotated a method with @Async annotation.
I have a class which implements a ApplicationListener interface. When I call my async method from this class, it never starts asynchronously and blocks the current thread. And When I call my async method from a spring controller class, It never blocks and starts asynchronously.
Why async method executed successfully from one class and not from the other class?
What am I doing wrong and How can I execute my async method on server startup??
Thanks in advance.
Edit: I tried using the InitializingBean interface, @PostConstruct, init-method approach to call my async method, but it never executed. Then I realized, my default lazy-init is true, So I make the lazy-init to false for my InitializingBean. Now it execute my asnyc method, but it blocks the current thread and now one more issue, I am facing is that My server didn't stop gracefully, but I have to stop my server forcefully.
Solution
First of all You don't need to implement ApplicationListener
interface. You are working with Spring - Application context is enough.
Second you are talking about Spring @Async
, it means that your task should be started from Application Context and Controller bean is a part of it.
You need to make sure that you have <annotation-driven>
in your spring xml file.
You can start your task on @PostConstruct function:
@Component
public class SampleBeanImpl implements SampleBean {
@Async
void doSomething() { … }
}
@Component
public class SampleBeanInititalizer {
@Autowired
private final SampleBean bean;
@PostConstruct
public void initialize() {
bean.doSomething();
}
}
Answered By - danny.lesnik
Answer Checked By - Marilyn (JavaFixing Volunteer)