2017-06-09 9 views
0

私はSpringブートに基づいて簡単なアプリケーションを持っています。LifecycleProcessorと開始シグナル(@SpringBootApplicationで@Autowireを使用)を使用

私はこの例ではXML構成を使用していません。

主成分はappMain(暗黙的なコンストラクタの自動配線を使用)であり、を実装するdataCollectorに依存します。これは、Springコンテナが作成された直後に呼び出されることが予想されるpublic void start()をオーバーライドして定義します。文書によると

:。

「どれSpring管理オブジェクトがそのインターフェイスを実装することができその後、ApplicationContextの自体が起動して、信号を停止受け、停止/ため例えば、実行時にシナリオを再起動し、それがこれらの呼び出しをカスケード接続しますそのコンテキスト内で定義されたすべてのライフサイクルの実装に適用されます。

しかし、このstartメソッドは呼び出されません。 start signalは明示的に定義してApplicationContextに送信する必要がありますか?コンテナが始まるときはいつも終わっていませんか?私はそれがコンテナのライフサイクルの一部だと思っていましたが、それはそうではないようです。それはどうしたの?

私のアプリケーション全体で開始し、停止する並列のデーモンのようなスレッドが必要です。このLifecycleProcessorは私が使うべきものか、あるいはSpringのいくつかのより良いオプションがありますか?

AppMain

import org.springframework.boot.Banner; 
import org.springframework.boot.SpringApplication; 
import org.springframework.boot.autoconfigure.SpringBootApplication; 
import org.springframework.context.ConfigurableApplicationContext; 
import org.springframework.context.annotation.DependsOn; 
import javax.annotation.PostConstruct; 

@SpringBootApplication 
@DependsOn("dataCollector") 
public class AppMain { 

    public LocColMain(ConfigurableApplicationContext context) { 
     this.context = context; 
    } 

    @PostConstruct 
    private void init() { 
     context.registerShutdownHook(); 
    } 

    public static void main(String[] args) { 
     SpringApplication app = new SpringApplication(AppMain.class); 
     app.setBannerMode(Banner.Mode.OFF); 
     app.run(args); 
    } 
} 

データ・コレクター

import org.slf4j.Logger; 
import org.slf4j.LoggerFactory; 
import org.springframework.context.LifecycleProcessor; 
import org.springframework.stereotype.Component; 

import javax.annotation.PostConstruct; 
import javax.annotation.PreDestroy; 
import java.sql.Timestamp; 
import java.util.Random; 

@Component 
public class DataCollector implements LifecycleProcessor { 
    private static final Logger log = LoggerFactory.getLogger(DataCollector.class); 

    private boolean isRunning; 

    private final DaoRssiCache daoRssiCache; 

    public DataCollector(DaoRssiCache daoRssiCache) { 
     this.daoRssiCache = daoRssiCache; 
    } 

    @Override 
    public void onRefresh() { 
     log.info("Data collector - REFRESH."); 
    } 

    @Override 
    public void onClose() { 
     log.info("Data collector - CLOSE."); 

     stop(); 
    } 

    @PreDestroy 
    public void destroy() { 
     log.info("Data collector - DESTROY."); 

     stop(); 
    } 

    @PostConstruct 
    public void init() { 
     log.info("Data collector - CREATED."); 
    } 

    @Override 
    public void start() { 
     log.info("Data collector - START."); 

     isRunning = true; 

     while (isRunning) { 
      // TODO: do some business stuff... 
     } 
    } 

    @Override 
    public void stop() { 
     log.info("Data collector - STOP."); 
     isRunning = false; 
    } 

    @Override 
    public boolean isRunning() { 
     return isRunning; 
    } 
} 

答えて

0

あなたは、バックグラウンドジョブの並列スレッドが必要な場合は、それを作成する必要があります。あなたの要件に応じてスレッドはdaemonになることができます。スレッドがジョブを完了するまで待つ必要がない場合は、デーモンとして指定することができ、アプリケーションのシャットダウン後にこのスレッドはタイムアウトなしで中断されます。

例:

class BackgroundJob extends Thread { 
    public BackgroundJob(boolean daemon) { 
     setDaemon(daemon); 
    } 
    //others logic 
} 
関連する問題