Spring引导从bean中的数据库预加载数据

时间:2016-02-16 08:46:33

标签: java spring datasource javabeans

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

子ID |父母身份

1 |空

2 | 1

3 | 1

4 | 2

等等......要求整个数据结构需要大约10秒钟我无法重新设计此表,因为它花费了太多时间(更多信息:Spring Repository performance issues with recursive ORM Class

现在,我正在考虑在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时,它再次起作用。

更新

@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();
}

2 个答案:

答案 0 :(得分:3)

您可以收听ApplicationReadyEvent,然后调用该方法(来自@ yglodt&#39; s answer)以初始化您的缓存。

示例代码:

@Component
public class MyEventsListener {

    @Autowired
    SkillsService skillsService;

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

还要记住,如果从SkillsService bean本身调用getAllSkills(),则不会访问缓存,因为只有在类的注入proxy上调用该方法时才会建议该方法。

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

public class Application {

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

}

答案 1 :(得分:2)

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只是在第一次被调用时执行一次,然后在没有调用方法的情况下从缓存管理器返回值。