使用Spring和ehcache进行缓存并不像预期的那样工作

时间:2017-03-23 16:30:09

标签: spring caching ehcache

我有一个Product模型对象 -

class ProductDTO {
    int id;
    String code;
    String description;

   //getters and setters go here
}

我正在编写一个服务(下面的代码),按ID或代码查找产品并返回其描述。我使用Spring 4和ehcache来缓存结果。

我有两种方法 - 一种用于按ID查找,另一种用于按代码查找 - 它们是getProductByCodegetProductById。两者都将描述作为字符串返回。他们通过调用getAllProducts()来返回所有产品的列表。然后,呼叫者在列表中搜索与id或代码匹配的产品并返回描述。

getAllProducts()还为每个产品调用了@CachePut的2个方法 - 通过键codeid将描述字符串保存在缓存中。

如果将codeid传递给getProductByCodegetProductById方法的相同参数,则缓存可正常工作。但是,如果我传递了不同的参数,则再次调用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;
    }
}

1 个答案:

答案 0 :(得分:1)

M. Deinum评论,问题来自注释,如CachePutCacheable,在运行时被转换为方面。并且该方法的主要限制是来自同一类的调用未被正确捕获。

当您在评论部分回复自己时,将带注释的方法移动到当前注入的另一种类型可以解决问题。