2016-09-28 2663 views
1

我有一个在Tomcat 8中部署的Spring Boot应用程序。当应用程序启动时,我想在Spring Autowires的某些依赖关系的后台启动一个工作线程。目前,我有这样的:Spring Boot - 在部署中启动后台线程的最佳方式

@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(); 
    } 

在我的泊坞测试环境中,这工作得很好 - 但是当我部署此给Tomcat 8我的Linux(Debian的杰西,爪哇8)主机我从来没有看到“正在启动用户线程”消息(并且线程未启动)。

+0

你阅读http://docs.spring.io/spring-boot/docs/current/api的javadoc /org/springframework/boot/context/web/SpringBootServletInitializer.html - 我不明白你为什么要使用'main'方法。 –

+0

因此,它也可以作为一个独立的服务器运行,没有Tomcat。 – Gandalf

+1

什么是在'tomcat'环境中调用这个'main'? –

回答

4

将应用程序部署到非嵌入式应用程序服务器时不调用主要方法。 启动线程最简单的方法是从bean构造函数中执行。 也是一个不错的主意,清理线程时的背景是封闭的,例如:

@Component 
class EventSubscriber implements DisposableBean, Runnable { 

    private Thread thread; 
    private volatile boolean someCondition; 

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

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

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

} 
+1

无法在类级别添加@Bean,请参阅https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/context/annotation/Bean.html –

+0

好点,我已将其更改为“@ Component”,不过您可以注册该bean,但是您真的想要。 – Magnus

0

你可以有一个豆iml ApplicationListener<ContextRefreshedEvent>它的onApplicationEvent将被称为只是开始你的线程,如果它还没有启动。我想你想要的ApplicationReadyEvent的方式。

相关问题