当前位置: 首页 > 知识库问答 >
问题:

如何在Spring启动时加载@Cache?

姜智渊
2023-03-14

我使用spring cache改进数据库查询,其工作原理如下:

@Bean
public CacheManager cacheManager() {
    return new ConcurrentMapCacheManager("books");
}

@Cacheable("books")
public Book getByIsbn(String isbn) {
    return dao.findByIsbn(isbn);
}

但是现在我想在启动时预填充完整的图书缓存。这意味着我要调用dao。findAll()并将所有值放入缓存。该例行程序不应仅定期安排。

但是,使用@Cacheable时,如何显式填充缓存?

共有3个答案

栾越
2023-03-14

一个选项是在启动时使用命令行运行程序填充缓存。

根据CommandLineRunner官方文档,它是:

接口用于指示bean在包含在SpringApplication中时应运行。

因此,我们只需要检索所有可用书籍的列表,然后使用CacheManager,填充书籍缓存。

@Component
public class ApplicationRunner implements CommandLineRunner {
    @Autowired
    private BookDao dao;

    @Autowired
    private CacheManager cacheManager;

    @Bean
    public CacheManager cacheManager() {
        return new ConcurrentMapCacheManager("books");
    }

    @Override
    public void run(String... args) throws Exception {

        List<Book> results = dao.findAll();

        results.forEach(book -> 
            cacheManager.getCache("books").put(book.getId(), book));
    }
}
鲁景山
2023-03-14

在使用@PostConstruct时,我遇到了以下问题:-即使调用了我想要缓存的方法,但在从swagger调用它之后,它仍然没有使用缓存的值。只是在再次打电话之后。

这是因为@PostConstruct对于缓存某些内容来说太早了。(至少我认为这是问题所在)

现在我在启动过程中使用它更晚,它没有问题:

@Component
public class CacheInit implements ApplicationListener<ApplicationReadyEvent> {

    @Override
    public void onApplicationEvent(ApplicationReadyEvent event) {
       //call service method
    }

}
孔礼骞
2023-03-14

只需像以前一样使用缓存,添加一个调度程序来更新缓存,下面是代码片段。

@Service
public class CacheScheduler {
    @Autowired
    BookDao bookDao;
    @Autowired
    CacheManager cacheManager;

    @PostConstruct
    public void init() {
        update();
        scheduleUpdateAsync();
    }

    public void update() {
        for (Book book : bookDao.findAll()) {
            cacheManager.getCache("books").put(book.getIsbn(), book);
        }
    }
}

确保您的KeyGenerator将返回一个参数的对象(默认)。或者,在BookService中公开putToCache方法,以避免直接使用cacheManager。

@CachePut(value = "books", key = "#book.isbn")
public Book putToCache(Book book) {
    return book;
}
 类似资料:
  • 问题内容: 我正在使用spring-cache来改善数据库查询,如下所示可以正常工作: 但是现在我想在启动时预先填充完整的图书缓存。这意味着我要调用并将所有值放入缓存。该例程应仅定期进行安排。 但是在使用时如何显式填充缓存? 问题答案: 像以前一样使用缓存,添加调度程序以更新缓存,下面是代码段。 确保你将为一个参数返回对象(默认)。否则,请公开其中的方法,以避免直接使用cacheManager。

  • 我想在应用程序启动时使用Spring ehCache将数据从数据库加载到缓存中,即在调用任何其他方法之前服务器启动时。我不想使用构造函数。请帮帮我。

  • 问题内容: 当Django启动时,如何从mysql数据库加载资源并将其放入内存(Redis)中,以供所有应用程序使用。 我已经看到了这个 [https://docs.djangoproject.com/en/dev/ref/applications/#django.apps.AppConfig.ready] 但是他们提到在ready函数中不使用db连接。我的网站启动时该怎么办? 我还可以在read

  • 问题内容: 我希望IPython或Python解释器在启动它们时自动加载模块。 可能吗? 例如,当我启动IPython时: 在教程页面中可以找到类似SymPy的live shell的 东西。 问题答案: 检查文件-您可以列出要在启动时加载的所有模块。

  • 问题内容: 我正在尝试从启动时自动加载模块,目前我在IPython启动库中有一个简单的脚本,其内容如下: 直接从外壳运行时可以正常工作,但是从脚本运行该行时,该模块似乎没有加载,我通过向其添加一些任意变量分配来确保已加载启动脚本: 并在启动IPython时(如预期的那样)预先分配了变量。 我试图在这里和这里寻找一些解决方案,但无处可寻,任何帮助将不胜感激,谢谢 问题答案: 我找到了一个解决方案,在