Montag, Januar 20, 2020

Spring Boot – Beste start in einen hintergrund-thread auf Bereitstellung

Ich habe eine Spring-Boot-Anwendung bereitgestellt, die in Tomcat-8. Wenn die Anwendung startet, möchte ich erst ein worker-Thread im hintergrund, der Frühling Autowires mit ein paar Abhängigkeiten. Derzeit habe ich dieses :

@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 meinem Andockfenster test environment das funktioniert gut – aber wenn ich Sie stellen diese auf meinem Linux (Debian Jessie, Java 8), die Gastgeber in Tomcat 8, die ich nie finden Sie in der „Start-Abonnenten Thread“ Nachricht (und den thread nicht gestartet).

  • So kann es laufen als standalone-server auch ohne Tomcat.
  • und was ist, ruft diese main im tomcat Umfeld?
  • Mit einer Methode annotiert @Bean in MyServer Klasse?
  • Sie sind sich der Tatsache bewusst, dass ein thread in einer EE Umgebung ist grundsätzlich eine schlechte Sache zu tun? Erstellen Sie einfach ein service im Frühjahr mit Anmerkungen versehen Sie es mit @Scheduled und laufen lassen, auf bestimmte Intervalle. Oder noch besser, warum brauchst du diesen thread? In der Regel gibt es bessere (und mehr Frühling integrierten) Lösungen.
InformationsquelleAutor Gandalf | 2016-09-28

2 Kommentare

  1. 7

    Der main-Methode wird nicht aufgerufen, wenn die Bereitstellung der Anwendung auf eine nicht-eingebettete application server.
    Der einfachste Weg starten, um ein thread zu finden, ist aus den Bohnen Konstruktor.
    Auch eine gute Idee, um aufzuräumen den thread, wenn der Rahmen geschlossen ist, zum Beispiel:

    @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;
        }
    
    }
    • Es ist nicht möglich, @Bean auf der class-Ebene finden Sie unter docs.Frühling.io/spring/docs/current/javadoc-api/org/…
    • Guter Punkt, habe ich geändert es zu @Component statt, obwohl Sie sich anmelden können, die Bohne, aber Sie wollen, wirklich.
    • Tut bedeutende Arbeit in den Konstruktor, wie das starten eines thread macht es sehr schwer, das Objekt getestet werden. Die Antwort von Snickers3192 sollte die akzeptierte Antwort
    • Fairer Punkt. Wenn Sie wollen, um in der Lage zu konstruieren, das Objekt, ohne den Faden, den Sie verwenden konnten, ein @PostConstruct annotation.
  2. 3

    Hätte man eine Bohne, welche impelements ApplicationListener<ContextRefreshedEvent> Es onApplicationEvent aufgerufen werden, starten Sie einfach Ihren thread gibt, falls nicht bereits begonnen. Ich denke, Sie wollen die ApplicationReadyEvent durch die Art und Weise.

    Bearbeiten
    Wie fügen Sie einen Haken an die Anwendung Kontext-Initialisierung Veranstaltung?

    @Component
    public class FooBar implements ApplicationListener<ContextRefreshedEvent> {
    
        Thread t = new Thread();
    
        @Override
        public void onApplicationEvent(ContextRefreshedEvent event) {
            if (!t.isAlive()) {
                t.start();
            }
        }
    }

Kostenlose Online-Tests