Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to start a daemon on server startup in spring

Tags:

java

spring

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.

like image 838
Dheeraj Kumar Aggarwal Avatar asked May 01 '12 08:05

Dheeraj Kumar Aggarwal


2 Answers

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();
  }
}
like image 64
danny.lesnik Avatar answered Sep 21 '22 20:09

danny.lesnik


Based on Spring's reference, use of @Async has limitations during start-up of the application:

@Async can not be used in conjunction with lifecycle callbacks such as @PostConstruct. To asynchronously initialize Spring beans you currently have to use a separate initializing Spring bean that invokes the @Async annotated method on the target then.

So, in your case, maybe it'd be good to have an InitializingBean implementation with your target bean and then start the daemon through that.

like image 21
nobeh Avatar answered Sep 20 '22 20:09

nobeh