Use cache in spring, need following steps:
Enable Cache
@Configuration
@EnableCaching
public class CachingConfig {
@Bean
public CacheManager cacheManager() {
return new ConcurrentMapCacheManager("categoryOrders");
}
}
The "categoryOrders" is a cache name. The ConcurrentMapCacheManager
can accept multiple caches.
Bind Annotation on Method
There are several annotations:
-
@Cacheable
The simplest way to enable caching behavior for a method is to demarcate it with @Cacheable and parameterize it with the name of the cache where the results would be stored:
@Cacheable("categoryOrders")
List<Order> findAllOrders() {
return findAll();
}
The first time the application will get all orders from database and cache it in "categoryOrders"
-
@CacheEvict
When the data of category has been changed, we want to clean the cache. So we can bind this annotation on the method to clean the cache.
@CacheEvict(value = "categoryOrders", allEntries = true)
public void cleanCategoryOrderCache() {
}
allEntries = true
means clean all data.
-
@CachePut
@CacheEvict
annotation is clean all data. Sometimes, you only need to update a fraction of data. You can use@CachePut
annotation.
@CachePut(value="categoryOrders")
public Order getOrder(String orderId) {...}
The difference between @CachePut
and @Cacheable
is that @CachePut
will invoke the method every time, but @Cacheable
will invoke this method at first time.
We can also add condition in those annotations, such as:
@CachePut(value="categoryOrders", condition="#order.type==1")
public Order getOrder(String orderId) {...}
@CachePut(value="categoryOrders", unless="#order.type==3")
public Order getOrder(String orderId) {...}
There are many parameters you can define in each annotation.
The thing you need pay attention is that the theory of spring cache is AOP. So when you call the cache method in the same class, the cache will not be work. such as:
public class CategoryOrderGenerator {
private CategoryOrderRepository categoryOrderRepository;
@Autowired
public CategoryOrderGenerator(CategoryOrderRepository categoryOrderRepository) {
this.categoryOrderRepository = categoryOrderRepository;
}
public List<CategoryOrder> getCategoryOrder(List<String> parameters)
return categoryOrderRepository.findAllCategoryOrders().stream()
.filter(....)
.map(....)
.collect(Collectors.toList());
}
@Cacheable("categoryOrders")
public List<CategoryOrder> getAll() {
return categoryOrderRepository.findAllCategoryOrders();
}
}
The "getCategoryOrder" method and cached "getAll()" are in same class. The "getCategoryOrder" call the "getAll()" method. So the cache will not work, because this two method are in same class. You can add the @Cacheable("categoryOrders")
to findAllCategoryOrders()
method in repository.
网友评论