simple-spring-memcached簡介

openkk 12年前發布 | 70K 次閱讀 緩存服務器 memcached

memcached是一款非常優秀的分布式緩存工具,有效提升了按主鍵檢索數據的性能問題。而simple-spring-memcached組件通過與spring框架整合,讓memcached的調用變得更加簡單。

simple-spring-memcached本質上是采用了AOP的方式來實現緩存的調用和管理,其核心組件聲明了一些Advice,當遇到相應的切入點時,會執行這些Advice來對memcached加以管理。

切入點是通過標簽的方式來進行聲明的,在項目開發時,通常在DAO的方法上加以相應的標簽描述,來表示組件對該方法的攔截
組件所提供的切入點主要包括以下幾種:
ReadThroughSingleCache、ReadThroughMultiCache、ReadThroughAssignCache
當遇到查詢方法聲明這些切入點時,組件首先會從緩存中讀取數據,取到數據則跳過查詢方法,直接返回。
取不到數據在執行查詢方法,并將查詢結果放入緩存,以便下一次獲取。
InvalidateSingleCache、InvalidateMultiCache、InvalidateAssignCache
當遇到刪除方法聲明這些切入點時,組件會刪除緩存中的對應實體
UpdateSingleCache、UpdateMultiCache、UpdateAssignCache
當遇到更新方法聲明這些切入點是,組件會更新緩存中對應的實體,以便下次從緩存中讀取出的數據狀態是最新的

simple-spring-memcached本身并不提供cache機制的實現,只是為了cache的調用更加簡單而設計的。
在cache的實現上使用的是第三方組件(如x-memcached和spy-memcached),官方給出了針對這兩種組件的相關配置

http://code.google.com/p/simple-spring-memcached/wiki/Getting_Started

simple-spring-memcached的使用:

1.首先在Spring配置文件中加入如下兩句:

<import resource="simplesm-context.xml" />
<aop:aspectj-autoproxy />
simplesm-context.xml封裝在simple-spring-memcached-*.jar文件當中,主要用來加載組件核心的Advice,供程序調度使用。
而由于simple-spring-memcached主要是基于AOP的代理,所以加入<aop:aspectj-autoproxy />讓代理機制起到作用。

2.定義memcached客戶端

memcached比較常用的java客戶端有兩種,spymemcached和xmemcached,xmemcached支持多線程

<bean name="defaultMemcachedClient" class="com.google.code.ssm.CacheFactory">
        <property name="cacheClientFactory">
            <bean class="com.google.code.ssm.providers.xmemcached.MemcacheClientFactoryImpl" />
        </property>
        <property name="addressProvider">
            <bean class="com.google.code.ssm.config.DefaultAddressProvider">
                <property name="address" value="192.168.7.131:11211" />
            </bean>
        </property>
        <property name="configuration">
            <bean class="com.google.code.ssm.providers.CacheConfiguration">
                <property name="consistentHashing" value="true" />
            </bean>
        </property>
    </bean>
com.google.code.ssm.CacheFactory是一個FactoryBean,會返回Cache實體供Advice使用
address屬性定義了緩存節點的IP地址和端口號

consistentHashing屬性定義了緩存節點的查找方法

3.實體的定義

memcached相當于一個功能強大的Map,通過Key/Value的形式來緩存POJO實體,在定義實體的時候,可通過@CacheKeyMethod標簽來為實體指定Key值,同時實體及實體的每個成員變量必須是可序列化的,可實現Serializable接口,或通過Externalizable接口來為實體指定序列化方法。

public class User implements Serializable {
    private static final long serialVersionUID = 7517080513591583073L;
    private String userId;
    private String username;
    private String password;
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    @CacheKeyMethod
    public String getUserId() {
        return userId;
    }
    public void setUserId(String userId) {
        this.userId = userId;
    }
}
4.DAO的定義
緩存操作通常是對DAO的方法進行攔截,加入必要的通知以達到增刪改查的效果

切入點的聲明主要通過之前提到的標簽來實現

public class UserDaoImpl implements IUserDao {
    private static final String NAMESPACE="ns";
    private Map<String,User> users=new HashMap<String,User>();
    @Override
    public void saveUser(User user) {
        users.put(user.getUserId(), user);
    }
    /**
     * 當執行getById查詢方法時,系統首先會從緩存中獲取userId對應的實體
     * 如果實體還沒有被緩存,則執行查詢方法并將查詢結果放入緩存中
     */
    @Override
    @ReadThroughSingleCache(namespace = NAMESPACE, expiration = 3600)
    public User getById(@ParameterValueKeyProvider String userId) {
        System.out.println(userId);
        return users.get(userId);
    }
    /**
     * 當執行updateUser方法時,系統會更新緩存中userId對應的實體
     * 將實體內容更新成@*DataUpdateContent標簽所描述的實體
     */
    @UpdateSingleCache(namespace = NAMESPACE, expiration = 3600)
    @Override
    public void updateUser(@ParameterValueKeyProvider @ParameterDataUpdateContent User user) {
        users.put(user.getUserId(), user);
    }
    /**
     * 當執行deleteUser方法時,系統會刪除緩存中userId對應的實體
     */
    @InvalidateSingleCache(namespace = NAMESPACE)
    @Override
    public void deleteUser(@ParameterValueKeyProvider String userId) {
        users.remove(userId);
    }
}

 本文由用戶 openkk 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!