zoukankan      html  css  js  c++  java
  • Spring Cache与Tair结合

    spring3.1.M1中的cache功能比较简便。可以与Tair结合,这样就不必每次缓存数据库结果集或者hsf结果的时候都写一段同样的代码。

    spring3.1.M1中的cache主要使用两个注解标记。

    @Cacheable:负责将方法的返回值加入到缓存中

    @CacheEvict:负责清除缓存

    @Cacheable 支持如下几个参数:

    value:缓存位置名称,不能为空,如果使用EHCache,就是ehcache.xml中声明的cache的name

    key:缓存的key,默认为空,既表示使用方法的参数类型及参数值作为key,支持SpEL

    condition:触发条件,只有满足条件的情况才会加入缓存,默认为空,既表示全部都加入缓存,支持SpEL

    @CacheEvict 支持如下几个参数:

    value:缓存位置名称,不能为空,同上

    key:缓存的key,默认为空,同上

    condition:触发条件,只有满足条件的情况才会清除缓存,默认为空,支持SpEL

    allEntries:true表示清除value中的全部缓存,默认为false

    例子:

    /**
     * TODO 如果没有注释,那么,你懂的
     *
     * @author : mulou.zzy
     *         Time: 下午3:51
     */
    @Component("dos")
    public class DoSomeThing {
    
    
        @Cacheable(value = "default", key="#a")
        public String doa(int a) {
    
            return (int)( Math.random()* 1000 )+ "";
    
        }
    
        @Cacheable(value = "default",condition="#a > 50")
        public String dob(int a) {
            return (int)(Math.random()* 1000 )+ "";
        }
        //清除掉全部缓存
        @CacheEvict(value="default", key = "#a")
        public  void delete(int a) {
            System.out.println("do delete when a  = " + a);
        }
    
    }

    实现结合Tair的Cache必须继承Spring的Cache接口

    package com;
    /**
     * 一个简单的Tair Cache
     *
     * @author : mulou.zzy
     *         Time: 下午3:31
     */
    public class TairCache implements Cache {
        Logger log = Logger.getLogger(Cache.class);
        @Resource
        private MultiClusterTairManager tairManager;
    
        private int nameSpace;
    
        public void setNameSpace(int nameSpace) {
            this.nameSpace = nameSpace;
        }
    
        private String name = "default";
    
        @Override
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        @Override
        public MultiClusterTairManager getNativeCache() {
            return tairManager;
        }
    
        @Override
        public TairResult get(Object key) {
            Result<DataEntry> result = tairManager.get(nameSpace, (Serializable) key);
            if (result != null) {
                if (result.isSuccess() && result.getValue() != null) {
                    TairResult tr = new TairResult();
                    tr.put((Serializable) result.getValue().getValue());
                    return tr;
                } else {
                    log.warn(result.isSuccess() ? "value为空" : result.getRc().getMessage());
                }
            }
            return null;
        }
    
        @Override
        public void put(Object key, Object value) {
            if (key != null || value != null) {
                if (key instanceof TairKey) {
                    TairKey tairKey = (TairKey) key;
                    this.isRcSuccess(this.tairManager.put(nameSpace, tairKey.getKey(), (Serializable) value, tairKey.getVersion(), tairKey.getTime()));
                }
                this.isRcSuccess(this.tairManager.put(nameSpace, (Serializable) key, (Serializable) value));
            }
    
        }
      //清除缓存
        @Override
        public void evict(Object key) {
            ResultCode rc = this.tairManager.delete(nameSpace, (Serializable) key);
            this.isRcSuccess(rc);
        }
      //tair返回是否成功
        public boolean isRcSuccess(ResultCode rc) {
            if (rc != null) {
                if (rc.isSuccess()) {
                    return true;
                } else {
                    log.warn(rc.getMessage());
                    return false;
                }
            }
            log.warn("获取不到ResultCode");
            return false;
        }
      //本来是清楚所有缓存方法,但是我们这里禁止掉。
        @Override
        public void clear() {
            System.out.println("not allow to clear");
        }
    }

    因为@Cacheable标记中没有设置缓存时间和version的地方,所以我封装了一个TairKey类,存储Key和Version、time

    但是这也不是一个好的解决方案, 目前我在用的是把key设置成String类型,在字符串末尾带上-version-time表示version和time

    /**
     * TODO 如果没有注释,那么,你懂的
     *
     * @author : mulou.zzy
     *         Time: 上午11:34
     */
    public class TairKey implements Serializable {
    
        Serializable key;
        int time = 0;
        int version = 0;
    
        public int getTime() {
            return time;
        }
    
        public int getVersion() {
            return version;
        }
    
        public void setTime(int time) {
            this.time = time;
        }
    
        public void setVersion(int version) {
            this.version = version;
        }
    
        public Serializable getKey() {
            return key;
        }
    
        public void setKey(Serializable key) {
            this.key = key;
        }
    }

    TairResult是封装了Tair返回的类

    /**
     * TODO 如果没有注释,那么,你懂的
     *
     * @author : mulou.zzy
     *         Time: 下午3:41
     */
    public class TairResult<T extends Serializable> implements Cache.ValueWrapper {
        private T result;
    
        /**
         *     Tair上的版本号
         *
         */
        private int version;
        /**
         *     存储时间,单位为秒
         */
        private int time;
    
        @Override
        public Object get() {
    
            return result;
        }
        public void put(T res){
            this.result = res;
        }
    }

    最后是配置的xml

    <?xml version="1.0" encoding="GBK"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:cache="http://www.springframework.org/schema/cache"
           xmlns:context="http://www.springframework.org/schema/context"
           xmlns:p="http://www.springframework.org/schema/p"
           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
               http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
                   http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-3.1.xsd
         http://www.springframework.org/schema/cache  http://www.springframework.org/schema/cache/spring-cache-3.1.xsd
              http://www.springframework.org/schema/p  http://www.springframework.org/schema/p/spring-p.xsd"
           default-autowire="byName">
        <cache:annotation-driven cache-manager="cacheManager"/>
        <context:annotation-config />
        <context:component-scan base-package="com"/>
        <bean id="tairManager" class="com.taobao.tair.impl.mc.MultiClusterTairManager"
              init-method="init">
            <property name="configID" value="ldbcommon-daily"/>
            <property name="dynamicConfig">
                <value type="java.lang.Boolean">true</value>
            </property>
        </bean>
        <!-- generic cache manager -->
        <bean id="cacheManager" class="org.springframework.cache.support.SimpleCacheManager">
            <property name="caches">
                <set>
                    <bean class="com.TairCache" p:name="default"/>
                </set>
            </property>
        </bean>
    
    </beans>

    然后跑测试类

    /**
     * TODO 如果没有注释,那么,你懂的
     *
     * @author : mulou.zzy
     *         Time: 下午3:08
     */
    public class Test {
    //    org.springframework.cache.ehcache.EhCacheCacheManager   ;
    //
    //
    //    org.springframework.cache.support.SimpleCacheManager   ;
    //    ConcurrentCacheFactoryBean   ;
    //    ConcurrentMapCache
    //}
    
        public static void  main(String s[]){
            ApplicationContext ac = new ClassPathXmlApplicationContext("T.xml");
            DoSomeThing dos = (DoSomeThing)ac.getBean("dos");
            System.out.println(dos.doa(1111));
            System.out.println(dos.doa(1111));
           dos.delete(1111);
            System.out.println(dos.doa(1111));
            System.out.println(dos.dob(1200));
            System.out.println(dos.dob(1200));
            dos.delete(1200);
            System.out.println(dos.dob(1200));
            System.out.println(dos.dob(11));
            System.out.println(dos.dob(11));
        }
    }
  • 相关阅读:
    数据类型
    springboot中get post put delete 请求
    图解SQL的inner join、left join、right join、full outer join、union、union all的区别
    【转】MyBatis之级联——一对一关系
    【转】浏览器同源政策及其规避方法(2)
    【转】浏览器同源政策及其规避方法(1)
    Spring Boot配置文件详解
    【BUG】Spring Mvc使用Jackson进行json转对象时,遇到的字符串转日期的异常处理(JSON parse error: Can not deserialize value of type java.util.Date from String[])
    【转】SpringBoot Mybatis 读取配置文件
    MySQL
  • 原文地址:https://www.cnblogs.com/huamulou/p/2949704.html
Copyright © 2011-2022 走看看