Memcached(三)、封装Memcached和Ehcache

本文对Ehcache和Memcached进行了简单的封装,这样对于客户端程序无需了解ehcache和memcached的差异,仅需要配置缓存的Provider类就可以在二者之间进行切换,Provider实现类通过Spring IoC注入。
cache.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING/DTD BEAN//EN"
        "http://www.springframework.org/dtd/spring-beans.dtd">

<beans>
    <bean id="cacheProvider" class="org.frank1234.spring.memcached.EhcacheCacheProvider">
    </bean>
    <bean id="cacheManager" class="org.frank1234.spring.memcached.CacheManager">
        <property name = "cache">
            <ref bean="cacheProvider"></ref>
        </property>
    </bean>
</beans>

public interface ICache {
    public void put(String key, Object obj) throws Exception;
    public Object get(String key) throws Exception;
    public void remove(String key) throws Exception;
}


public class EhcacheCacheProvider implements ICache{
    private static CacheManager manager ;
    private static Cache ehcache;
    public EhcacheCacheProvider(){
        manager =  CacheManager.getInstance();
        ehcache = manager.getCache("helloworldCache");
    }


    @Override
    public void put(String key, Object obj) throws Exception {
        Element elemnt = new Element(key,obj);
        ehcache.put(elemnt);
    }

    @Override
    public Object get(String key) throws Exception {
        Element element = ehcache.get(key);
        return element.getObjectValue();
    }

    @Override
    public void remove(String key) throws Exception {
        ehcache.remove(key);
    }
}


public class MemcachedCacheProvider implements ICache {
    static {
        try {
            initPool();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    private static MemCachedClient client;

    private static void initPool() throws Exception{
        Properties props = getProperties();
        String[] servers = ((String)props.get("servers")).split(",");
        SockIOPool pool = SockIOPool.getInstance();
        pool.setServers(servers);
        pool.setFailover(Boolean.valueOf((String)props.get("failover")));
        pool.setInitConn(Integer.parseInt((String)props.get("initConn")));
        pool.setMinConn(Integer.parseInt((String)props.get("minConn")));
        pool.setMaxConn(Integer.parseInt((String)props.get("maxConn")));
        pool.setMaintSleep(Integer.parseInt((String)props.get("maintSleep")));
        pool.setNagle(Boolean.valueOf((String)props.get("magle")));
        pool.setSocketTO(Integer.parseInt((String)props.get("socketTO")));
        pool.setAliveCheck(Boolean.valueOf((String)props.get("aliveCheck")));
        pool.initialize();
    }
    private static Properties getProperties() throws Exception{
        Properties props = new Properties();
        InputStream in = MemcachedCacheProvider.class.getResourceAsStream("/memcached.properties");
        props.load(in);
        return props;
    }
    public MemcachedCacheProvider(){
        client = new MemCachedClient();
    }

    @Override
    public void put(String key, Object obj) throws Exception {
        client.set(key.toString(),obj);

    }

    @Override
    public Object get(String key) throws Exception {
        return client.get(key);
    }

    @Override
    public void remove(String key) throws Exception {
        client.delete(key);
    }
}


public class CacheManager {
    private ICache cache;

    public void setCache(ICache cache) {
        this.cache = cache;
    }

    public ICache getCache() throws Exception{
        return cache;
    }
}


public class CacheMain {
    @BeforeClass
    public static void setUpBeforeClass() throws Exception {
    }

    @AfterClass
    public static void tearDownAfterClass() throws Exception {
    }

    @Before
    public void setUp() throws Exception {

    }

    @After
    public void tearDown() throws Exception {

    }
    @Test
    public void testCache() throws Exception{
        ApplicationContext factory = new ClassPathXmlApplicationContext("cache.xml");
        CacheManager cacheManager = (CacheManager)factory.getBean("cacheManager");
        ICache cache = cacheManager.getCache();
        cache.put("key","value");
        System.out.println(cache.get("key"));
    }
}


ehcache.xml
<?xml version="1.0" encoding="UTF-8"?>

<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:noNamespaceSchemaLocation="ehcache.xsd" updateCheck="false"
         monitoring="autodetect" dynamicConfig="true">
    <!-- 将缓存数据写到硬盘上的目录,文件名为"缓存名1.data"的隐藏文件,程序运行结束后会自动删除,如果要查看可以通过Thread.sleep(60*1000)暂停住程序-->
    <diskStore path="d:/ehcache"/>
    <!--默认的缓存策略
     maxElementsInMemory :内存中存放的最大对象数,这是是对象的数量,maxBytesLocalHeap是对象的大小,jdk不提供直接计算对象大小的api,ehcache实现了计算对象大小的功能。具体可参见源码cache.calculateInMemorySize(),计算方法比较复杂。
     eternal:true表示永不过期,默认是false,如果设置成true,则timeToIdleSeconds和timeToLiveSeconds就失效了。
     overflowToDisk:true表示如果缓存的数量超过了maxElementsInMemory则将缓存数据放入硬盘中,
     timeToIdleSeconds:允许对象处于空闲状态的时间,超过此时间则过期,清掉缓存数据。
     timeToLiveSeconds:允许对象最大存活时间,超过此时间则过期,清掉缓存数据。这个时间大于timeToIdleSeconds才有意义。
     memoryStoreEvictionPolicy:当达到maxElementsInMemory限制时,Ehcache将会根据指定的策略去清理内存。可选策略有:LRU(最近最少使用,默认策略)、FIFO(先进先出)、LFU(最少访问次数)。


     -->
    <defaultCache  maxElementsInMemory="1000" eternal="false"
                  overflowToDisk="true" timeToIdleSeconds="30" timeToLiveSeconds="60">
    </defaultCache>

    <cache name="helloworldCache"  maxElementsInMemory="1000"
           maxEntriesLocalDisk="10000" eternal="false" overflowToDisk="true"
           diskSpoolBufferSizeMB="20" timeToIdleSeconds="10" timeToLiveSeconds="20"
           memoryStoreEvictionPolicy="LFU"   />
</ehcache>

memcached.properties
servers=localhost:11211
failover=true
initConn=10
minConn=5
maxConn=250
maintSleep=30
nagle=false
socketTO=3000
aliveCheck=true

你可能感兴趣的:(memcached,ehcache,spring ioc)