1

AppState私は 2 つの Beanを持つスプリング ブート アプリケーションを持っていますUsersAppState自動配線するため、Bean に依存しUsersます。2 つの Bean のスケルトン コードは次のとおりです。

@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

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

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

メソッドが 2 回トリガーされload()ていることに気付きました。おそらく 1 回は、 Bean が作成された直後のスケジューリング中に 1 回です。そのため、 inへの呼び出しを削除しました。これにより、冗長な通話の問題が修正されました。Usersinit()load()Usersload()init()

ただし、データがまだ入力されていないにもかかわらず、Bean が作成されるAppStateとすぐにサービスが開始されることがわかりました。この間、クエリを実行した場合、サービスは 0 ユーザーを返すため、これは私にとって危険です。UsersUsers

次のいずれかについてサポートが必要です。

  • Bean が で完了したときに、すべてのユーザー情報が含まれていることを確認するために にload()戻る必要がありますか? このルートに行く場合、の冗長な実行を防ぐにはどうすればよいですか?init()PostConstructload()

  • load()を除外する必要がある場合、実行しない限り準備ができていないinit()ことを確認するにはどうすればよいですか? 次のコードを使用してみましたが、ハングします。AppStateUsersload()AppState

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

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

1 に答える 1

2

flagクラスにa を持ち、 trueinit() が終了したらに設定することをお勧めします。load()ifflagがまだ設定されていない場合は、次のように実行をスキップできます。

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
    } 
}

また、別の解決策は、設定initialDelayされたミリ秒数だけ最初の実行を遅らせる@Scheduledアノテーション (ドキュメントはこちら) で設定することです。

    @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
    }
于 2016-04-13T21:38:47.660 に答える