java - 在启动 spring boot 服务之前等待依赖项加载

标签 java spring-boot autowired postconstruct spring-scheduled

我有一个 Spring Boot 应用程序,它有两个 bean - AppStateUsersAppState 依赖于 Autowiring 的 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 bean 之后立即调度 load()。因此,我在 init() 中删除了对 load() 的调用。这解决了冗余调用问题。

但是,现在我发现只要创建了 AppStateUsers bean,我的服务就会启动,即使 Users 尚未创建尚未填充数据。这对我来说是有风险的,因为在此期间,如果查询该服务,将返回 0 个用户。

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

  • 我是否应该将 load() 移回 init() 以确保当使用 PostConstruct 完成该 bean 时,它有所有用户信息吗?如果我走这条路,如何防止 load() 的冗余运行?

  • 如果load()应该远离init(),我如何确保AppState尚未准备好,除非Users 已执行load()?我尝试在 AppState 中使用以下代码,但它只是挂起。

代码如下。

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

最佳答案

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

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注释(文档 here ),这会将第一次执行延迟配置的毫秒数,例如:

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

关于java - 在启动 spring boot 服务之前等待依赖项加载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36609785/

相关文章:

java - Java 和 Python 可以共存于同一个应用程序中吗?

java - 如何从 Web 应用程序中存在的类访问 ear 的 list 文件?

java - 如何在 Lucene 中查询 ">"、 "<"和 "<>"

java - 如何摆脱自动安装新表

java - 如何使用 graphql-java 和 graphql-java-servlet 编写 GraphQL 订阅的解析器?

java - Spring项目中hibernate Autowiring 的小麻烦,未找到bean错误

java - Java中如何定义全局数组并在不同类中调用

java - 无法自动配置数据源 : 'spring.datasource.url'

java - 我可以拦截 Spring @Autowired 进程来进行验证检查吗?

java - Spring @Autowired 是按名称还是按类型注入(inject) bean?