可否让 Cache 变得更加优雅?

本文是《轻量级 Java Web 框架架构设计》的系列博文。 java

以前实现了一个简单的 Cache 插件,主要用于 Service 层,为了减小数据库的访问次数,将数据放入 Cache 中缓存起来。在 Service 中直接使用了 Cache API,这样致使 Service 代码变得更加复杂,Cache 逻辑与核心逻辑纠缠在一块儿,我想着应该是一个很明显的缺点吧具体的开发过程,请参考《Smart Plugin —— 从一个简单的 Cache 开始》。 数据库

后来 Bieber 对 Cache 作了一个优化,结合了 Spring Cache 的注解式配置,让 Service 中所涉及的 Cache 操做分离出来,充分利用了 AOP 的思想,经过使用 Smart 的 Aspect(切面类)来实现此功能。你们能够阅读这篇博文《Smart Framework 缓存插件的实现》。 缓存

我下面打算与你们交流的这样一个思路: 架构

有些插件,好比:Cache、Log、Performance 等,实际上他们都带有 AOP 的色彩,都是为了在执行目标方法的先后分别作点事情。就 Cache 插件而言,它应该本身提供一个 Aspect,并将此 Aspect 融入到 Smart AOP 环境中,而无需在应用程序中,定义一个 Cache 的 Aspect(这样或许有些多余)。也就是说,Cache 插件的核心就是一个 Aspect,此外才是用于控制缓存的 API,而这些 API 是给插件自身来调用的,而不是给应用程序调用而已。 框架

我想像这样来实现缓存: ide

@Bean
@Cachable
public class CustomerServiceImpl extends BaseService implements CustomerService {

    @Override
    @CachePut("customer_list_cache")
    public List<Customer> getCustomerList() {
        return DataSet.selectList(Customer.class, null, null);
    }

    @Override
    @CacheClear({"customer_list_cache", "customer_cache"})
    public boolean deleteCustomer(long id) {
        return DataSet.delete(Customer.class, "id = ?", id);
    }

    @Override
    @CachePut("customer_cache")
    public Customer getCustomer(long id) {
        return DataSet.select(Customer.class, "id = ?", id);
    }

    @Override
    @CacheClear({"customer_list_cache", "customer_cache"})
    public boolean updateCustomer(long id, Map<String, Object> fieldMap) {
        return DataSet.update(Customer.class, fieldMap, "id = ?", id);
    }

    @Override
    @CacheClear({"customer_list_cache", "customer_cache"})
    public boolean createCustomer(Map<String, Object> fieldMap) {
        return DataSet.insert(Customer.class, fieldMap);
    }
}

在以上代码中,在类上面使用了 Cachable 注解,说明这个类是具有缓存特性的(可缓存的)。在须要缓存的方法上,使用了 CachePut 注解或 CacheClear 注解,前者用于将数据放入缓存,后者用户从缓存中清空数据(也就是使缓存消失)。 优化

例如,在 getCustomerList 方法中,使用了 CachePut 注解,在其注解参数中定义了 Cache 名称(customer_list_cache)。在实际运行时,先从 Cache 里获取数据,若是没有,则从 DB 中获取,最后将数据放回 Cache 中。这个逻辑都是在 Cache 插件中实现的。 spa

又如,在 deleteCustomer 方法中,使用了 CacheClear 注解,此时定义了两个 Cache 名称(customer_list_cache 与 customer_cache)。须要说明的是,这个 Service 中存在两个 Cache,一个用于缓存 customerList 数据,另外一个用于缓存 customer 数据。当删除一个 Customer 时,首先在 DB 中进行,而后刷新缓存,此时须要一并刷新所涉及到该 Customer 的全部 Cache,因此这里在 CacheClear 注解中定义了两个 Cache。 .net

后面几个方法与以上两个方法相似。其实 Cache 要干的事情,也就这两个方面(此时没有考虑 Cache 的淘汰策略)。 插件

个人问题是,这样的实现感受粒度有些粗,由于控制的在方法级别上,有没有可能将 Cache 控制在方法的内部呢?实际状况我想或许会比这个案例复杂,你们认为这种方式可行吗?

期待朋友们的解惑......

相关文章
相关标签/搜索