mem*_*und 14 java spring spring-cache
我正在使用spring-cache来改进数据库查询,其工作正常如下:
@Bean
public CacheManager cacheManager() {
return new ConcurrentMapCacheManager("books");
}
@Cacheable("books")
public Book getByIsbn(String isbn) {
return dao.findByIsbn(isbn);
}
Run Code Online (Sandbox Code Playgroud)
但现在我想在启动时预先填充完整的书籍缓存.这意味着我想调用dao.findAll()
并将所有值放入缓存中.此例程不应仅定期安排.
但是如何在使用时显式填充缓存@Cacheable
?
Lok*_*oki 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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
确保您KeyGenerator
将返回一个参数的对象(默认情况下).或者,将putToCache
方法公开BookService
以避免直接使用cacheManager.
@CachePut(value = "books", key = "#book.isbn")
public Book putToCache(Book book) {
return book;
}
Run Code Online (Sandbox Code Playgroud)
小智 7
使用@PostConstruct时,我遇到了以下问题:-即使调用了我想缓存的方法,从招摇动的方法调用后,它仍然没有使用缓存的值。只有在再次调用它之后。
那是因为@PostConstruct缓存某些内容还为时过早。(至少我认为这是问题所在)
现在,我在启动过程中使用的时间更晚,并且可以正常使用:
@Component
public class CacheInit implements ApplicationListener<ApplicationReadyEvent> {
@Override
public void onApplicationEvent(ApplicationReadyEvent event) {
//call service method
}
}
Run Code Online (Sandbox Code Playgroud)
一个选项是使用CommandLineRunner
在启动时填充缓存。
从官方 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));
}
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
21486 次 |
最近记录: |