我有這樣一個Product
模型對象 -緩存與春的Ehcache不工作按預期
class ProductDTO {
int id;
String code;
String description;
//getters and setters go here
}
我寫一個服務(下面的代碼),通過ID或代碼查找產品並返回其描述。我正在使用Spring 4和ehcache來緩存結果。
我有2個方法 - 一個用於查找id和一個用代碼查找 - 他們是getProductByCode
和getProductById
。兩者都以字符串的形式返回描述。他們通過致電getAllProducts()
返回所有產品的列表。呼叫者然後在列表中搜索與id或代碼匹配的產品並返回描述。
getAllProducts()
還會爲每個產品調用2種方法並使用@CachePut
- 通過鍵code
和id
將描述字符串保存在緩存中。
如果將相同參數傳遞給code
或id
至getProductByCode
和getProductById
方法,緩存工作正常。但是如果我通過一個不同的參數,再次調用getAllProducts()
。
我該如何實現預期的行爲 - 每次調用getAllProducts()
時,所有描述都被緩存,隨後的調用將查找緩存而不是去存儲庫?
public class ProductServiceImpl implements ProductService {
@Autowired
ProductsRepository ProductRepo;
@Override
public List<ProductDTO> getAllProducts() {
List<ProductDTO> products = ProductRepo.getAllProducts();
for(ProductDTO prodDTO : products) {
String desc = prodDTO.getDescription();
String code = prodDTO.getCode();
int id = prodDTO.getId();
putDescriptionInCache(desc, code);
putDescriptionInCache(desc, id);
}
return products;
}
@CachePut(value = "products", key = "#id")
public String putDescriptionInCache(String description, int id){
return description;
}
@CachePut(value = "products", key = "#code")
public String putDescriptionInCache(String description, String code){
return description;
}
@Override
@Cacheable(value="products", key="#id")
public String getProductById(Integer id) throws NullPointerException {
String dtoDesc = null;
List<ProductDTO> products = getAllProducts();
for(ProductDTO currDTO : products) {
int currId = currDTO.getId();
if(id.equals(new Integer(currId))) {
dtoDesc = currDTO.getDescription();
}
}
return dtoDesc;
}
@Override
@Cacheable(value="products", key="#code")
public String getProductByCode(String code) throws NullPointerException {
String dtoDesc = null;
List<ProductDTO> products = getAllProducts();
for(ProductDTO currDTO : products) {
String currCode = currDTO.getCode();
if(currCode.equals(code)) {
dtoDesc = currDTO.getDescription();
}
}
return dtoDesc;
}
}
緩存是使用AOP實現的。 AOP使用代理應用,因此只適用於進入對象的方法調用。內部方法調用不通過代理,因此這兩個方法調用基本上是徒勞的。 –
謝謝M.Deinum。這些信息與另一篇文章(對不起,我現在失去了它的鏈接)有所幫助。我將兩個putDescriptionInCache()方法都移到了較低層(ProductsRepository內),並將以下注釋添加到getProductByCode()和getProductById() - @Cacheable(「products」)。這樣,第一次調用通過getAllProducts()並緩存數據。另外,我的ProductRepository還有其他幾個方法 - getDirectionalTextById()和getDirectionalTextByCode() - 每個方法都有SQL來獲取描述。我從上面一層的同名方法中調用這些方法。 – lenniekid