在启动 spring 引导服务之前等待依赖项加载

Wait for dependencies to load before starting spring boot service

我有一个 spring 引导应用程序,它有两个 bean - AppStateUsersAppState 取决于 bean Users,因为它会自动装配它。两个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();
    }
}

我注意到 Users 中的方法 load() 被触发了两次 - 可能是在 init() 期间触发一次,另一次是在 Users 之后调度 load() =] bean 已经创建。所以我在 init() 中删除了对 load() 的调用。这解决了冗余调用问题。

但是,现在我发现我的服务在 AppStateUsers bean 创建后立即启动,即使 Users 尚未填充数据。这对我来说是有风险的,因为在此期间,如果被查询,将有 return 0 个用户。

我需要以下任何方面的帮助。

代码如下

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

我建议在 class 中设置一个 flag,并在 init() 完成后将其设置为 true。如果还没有设置flag,可以跳过load()的执行,例如:

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,这将延迟第一次执行配置的毫秒数,例如:

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