我有一个Product
模型对象 -
class ProductDTO {
int id;
String code;
String description;
//getters and setters go here
}
我正在编写一个服务(下面的代码),按ID或代码查找产品并返回其描述。我使用Spring 4和ehcache来缓存结果。
我有两种方法 - 一种用于按ID查找,另一种用于按代码查找 - 它们是getProductByCode
和getProductById
。两者都将描述作为字符串返回。他们通过调用getAllProducts()
来返回所有产品的列表。然后,呼叫者在列表中搜索与id或代码匹配的产品并返回描述。
getAllProducts()
还为每个产品调用了@CachePut
的2个方法 - 通过键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;
}
}
答案 0 :(得分:1)
由M. Deinum评论,问题来自注释,如CachePut
或Cacheable
,在运行时被转换为方面。并且该方法的主要限制是来自同一类的调用未被正确捕获。
当您在评论部分回复自己时,将带注释的方法移动到当前注入的另一种类型可以解决问题。