繁体   English   中英

Spring Boot从Bean中的数据库预加载数据

[英]Spring boot preloading data from database in bean

我要的是在一个表中具有递归关系的元素:

儿童编号| 家长编号

1 | 空值

2 | 1

3 | 1

4 | 2

依此类推...要花费整个数据结构大约10秒钟的时间,目前我无法重新设计该表,因为它花费了太多时间(有关更多信息: 递归ORM类的Spring Repository性能问题

现在,我正在考虑在春季启动期间将所有数据预加载到Bean中,以便客户端与Bean“通信”,并更新Bean和数据库中的数据。 我认为启动需要多长时间无关紧要,但是用户必须等待多长时间才有意义。

到目前为止,我还没有对其进行预加载。 我试图创建一个像这样的bean:

public class AppConfig extends WebMvcConfigurerAdapter {
...
@Autowired
SkillDAO skillDAO
...
@Bean(name="allSkills")
public List<Skill> allSkills(){
    return skillDAO.findBySkill(null);
}
...

它不起作用,因为出现错误:

原因:org.springframework.beans.factory.BeanCurrentlyInCreationException:创建名称为'dataSource'的bean时出错:当前正在创建请求的bean:是否存在不可解析的循环引用?

顺便说一下,我在AppConfig中创建了所有的bean。 当我删除此“ allSkills” bean时,它又可以工作了。

UPDATE

@Component
public class MyListener {

@Autowired
private SkillDAO skillDAO;

@EventListener
public void onApplicationReady(ApplicationReadyEvent ready) {
    System.out.println("++++++++++++++ HALLO +++++++++++++");
    skillDAO.findBySkill(null);
}
}

...

@Bean(name="skillBean")
public MyListener myListener() {
    return new MyListener();
}

您可以侦听ApplicationReadyEvent ,然后调用方法(来自@yglodt的answer )以初始化缓存。

示例代码:

@Component
public class MyEventsListener {

    @Autowired
    SkillsService skillsService;

    @EventListener
    public void onApplicationReady(ApplicationReadyEvent ready) {
        skillsService.getAllSkills();
    }
}

还要记住,如果您从SkillsService bean本身内部调用getAllSkills() ,则不会访问缓存,因为仅在对该类的注入代理上调用该方法时才建议使用该方法。

如果要将应用程序部署为可执行jar(而不是war文件),那么最简单的解决方案是从您的main方法调用要在启动时运行的代码:

public class Application {

    public static void main(String[] args) {
        ConfigurableApplicationContext context = SpringApplication.run(Application.class, args);
        SkillsService skillsService = context.getBean(SkillsService.class);
        skillsService.getAllSkills();
    }

}

Cache可以轻松解决您的需求。

理想情况下,您将拥有一个可以返回技能的方法的Service

该方法看起来像这样:

import org.springframework.cache.annotation.Cacheable;

@Cacheable(value = "skills", key = "#root.methodName")
public List<Skill> getAllSkills() {
    return ... your skills ...;
}

要在Spring Boot中启用缓存,请将@EnableCaching批注添加到您的配置类中,并添加一个Bean来对其进行配置:

import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.concurrent.ConcurrentMapCacheManager;

@Bean
public CacheManager cacheManager() {
    return new ConcurrentMapCacheManager("skills", "othercachename");
}

这样,方法getAllSkills只会在第一次调用时执行一次,然后从缓存管理器返回值,甚至不调用该方法。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM