Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring Boot - Best way to start a background thread on deployment

I have a Spring Boot application deployed in Tomcat 8. When the application starts I want to start a worker Thread in the background that Spring Autowires with some dependencies. Currently I have this :

@SpringBootApplication
@EnableAutoConfiguration
@ComponentScan
public class MyServer extends SpringBootServletInitializer {   

    public static void main(String[] args) {
        log.info("Starting application");
        ApplicationContext ctx = SpringApplication.run(MyServer.class, args);
        Thread subscriber = new Thread(ctx.getBean(EventSubscriber.class));
        log.info("Starting Subscriber Thread");
        subscriber.start();
    }

In my Docker test environment this works just fine - but when I deploy this to my Linux (Debian Jessie, Java 8) host in Tomcat 8 I never see the "Starting Subscriber Thread" message (and the thread is not started).

like image 379
Gandalf Avatar asked Sep 28 '16 02:09

Gandalf


People also ask

What does SpringApplication run () do?

SpringApplication#run bootstraps a spring application as a stand-alone application from the main method. It creates an appropriate ApplicationContext instance and load beans. It also runs embedded Tomcat server in Spring web application.

How do I use TaskExecutor in spring boot?

The first step is to add the TaskExecutor configuration to our Spring application. Once we have our executor set up, the process is simple. We inject the executor to a Spring component and then we submit Runnable classes containing the tasks to be executed.

What are the 3 main concepts spring boot provides when it starts your application?

Spring MVC With simple concepts like Dispatcher Servlet, ModelAndView, and View Resolver, it makes it easy to develop web applications.


1 Answers

The main method is not called when deploying the application to a non-embedded application server. The simplest way to start a thread is to do it from the beans constructor. Also a good idea to clean up the thread when the context is closed, for example:

@Component
class EventSubscriber implements DisposableBean, Runnable {

    private Thread thread;
    private volatile boolean someCondition;

    EventSubscriber(){
        this.thread = new Thread(this);
        this.thread.start();
    }

    @Override
    public void run(){
        while(someCondition){
            doStuff();
        }
    }

    @Override
    public void destroy(){
        someCondition = false;
    }

}
like image 59
Magnus Avatar answered Oct 01 '22 19:10

Magnus