0

私は2つの豆(AppStateUsers)を持つスプリングブートアプリケーションを持っています。 AppStateは、Usersという豆に依存しています。 2つのBeanのスケルトンコードは次のとおりです。 Users Beanが作成された直後load()をスケジューリングするときinit()中に、おそらく一度やその他の時間 -春のブートサービスを開始する前に依存関係がロードされるのを待ちます

@Component 
@EnableScheduling 
public class Users { 
    @Getter // lombok 
    private List<String> users; 

    @PostConstruct 
    public void init(){ 
     users = new ArrayList<>(); 
     load(); // I removed this later 
    } 

    @Scheduled(fixedRate = 3600000) 
    public void load(){ 
     // load list of users from (say) a file and populate ArrayList 'users' 
     // this method takes at least 3 mins to finish 
    } 
} 

AppStateは私がUsersload()方法は二回トリガーなっていたことに気づい

@Component 
public class AppState { 
    @Atowired 
    private Users users; 

    public List<String> getUsers(){ 
     return users.getUsers(); 
    } 
} 

です。そこで、load()への電話をinit()に削除しました。これにより、冗長コールの問題が修正されました。

しかし、Usersにまだデータが入力されていなくても、AppStateUsersのBeanが作成されるとすぐにサービスが開始されることがわかりました。これは、この時間中に問い合わせを受けたユーザーが0人を返すため、私にとっては危険です。

私は次のいずれかのヘルプが必要です。

  • 私はload()はBeanがPostConstructで行われたとき、それはすべてのユーザー情報を持っていないことを確認するために戻ってinit()に移動すべきか?私がこのルートに行くと、load()の冗長実行を防ぐ方法はありますか? load()init()の外に滞在する必要がある場合は

  • は、どのように私はUsersload()を実行した場合を除きAppStateの準備ができていないことを確認することができますか?私はAppStateで次のコードを使用しようとしましたが、ちょうどハングします。

コードは次のとおりです。

@PostConstruct 
public void appStateInit(){ 
    while(users.getUsers().size()==0){ 
     try{ 
      Thread.sleep(10000); // sleep 10s 
     }catch(whatever){ 
     } 
    } 
} 

答えて

2

私はクラスでflagを持つし、init()が終了した後trueに設定することをお勧め。

private AtomicBoolean shouldExecute; 

@PostConstruct 
    public void init(){ 
     users = new ArrayList<>(); 
     shouldExecute = true; 
    } 

@Scheduled(fixedRate = 3600000) 
public void load(){ 
    if(shouldExecute){ 
     // load list of users from (say) a file and populate ArrayList 'users' 
    // this method takes at least 3 mins to finish 
    } 
} 

また、別の解決策は、ミリ秒単位の構成された数で最初の実行を遅らせる@Scheduled注釈(ドキュメントhere)でinitialDelayを設定するには、次のようになります。flagは例えば、まだ設定されていない場合は、load()の実行をスキップすることができます例:

@Scheduled(fixedRate = 3600000, initialDelay=180000) 
    public void load(){ 
     // load list of users from (say) a file and populate ArrayList 'users' 
     // this method takes at least 3 mins to finish 
    } 
+0

ありがとうございます。私は 'initialDelay'アプローチが好きです。 – Nik

関連する問題