spring-cache

    spring-cache支持将现有缓存服务器配置为基于注解的缓存,本人所用过的就是作数据层缓存;

    首先,说一个踩过的坑:

        不同环境的切换,将会导致每个环境的spring-cache的结果不同,从而数据不一致,其实这个表面看起来大家

都明白,但是出现坑的原因是在于预上线环境的存在,如果预上线和线上的缓存不是同一套,那么在预上线作修改就

会导致预上线改数据库了并更新缓存,但是线上的数据库与缓存数据就不一致了。

    其实,说下配置方式。    

    spring-cache.xml

    <cache:annotation-driven cache-manager="jedisCacheManager" />

    <bean id="jedisCacheManager" class="wdm.yong.spring.jedis.JedisCacheManager">

        <property name="cacheStoreJedisHashRouter">

            <bean class="wdm.yong.cache.spring.jedis.CacheStoreJedisHashRouter" />

        </property>

        <property name="serializer">

            <bean class="wdm.yong.cache.spring.jedis.JsonSerializer" />

        </property>

        <property name="config">

            <bean class="org.apache.commons.pool2.impl.GenericObjectPoolConfig">

                <property name="maxTotal" value="400" />

                <property name="maxIdle" value="100" />

                <property name="maxWaitMillis" value="1000" />

                <property name="testOnBorrow" value="false" />

                <property name="testWhileIdle" value="false"/>

            </bean>

        </property>

        <property name="expires" value="604800" /><!--7 days -->

    </bean>

    

    JedisCacheManager

    

    public class JedisCacheManager extends AbstractCacheManager {

    private static final Logger logger = LoggerFactory.getLogger(JedisCacheManager.class);

    

    private List<Cache> cacheList;

    private List<JedisPool> jedisPoolList;

    private Map<String, String> namedClients;

    

    private int expires;

    private Serializer serializer;

    private CacheStoreJedisHashRouter cacheStoreJedisHashRouter;

    private GenericObjectPoolConfig config = new GenericObjectPoolConfig();

    }

 

    路由类

    

public class CacheStoreJedisHashRouter implements CacheStoreRouter<JedisPool> {

    private static final Logger logger = LoggerFactory.getLogger(CacheStoreJedisHashRouter.class);

 

    @Override

    public JedisPool pickUp(List<JedisPool> cacheStores, String cacheName, Object key) {

        int hashCode = new StringBuilder().append(cacheName).append(String.valueOf(key)).toString().hashCode();

        logger.debug("cacheName={}, key={}, hashCode={}", new Object[]{cacheName, key, hashCode});

        return cacheStores.get(Math.abs(hashCode) % cacheStores.size());

    }

}

    JedisCache类

public class JedisCache implements Cache {

    private static final Logger logger = LoggerFactory.getLogger(JedisCache.class);

    private String name;

    private List<JedisPool> jedisPoolList;

    private CacheStoreRouter<JedisPool> cacheStoreRouter;

    private Serializer serializer;

    private int expires;

 

    public JedisCache(String name, List<JedisPool> jedisList, CacheStoreRouter<JedisPool> cacheStoreRouter, Serializer serializer, int expires) {

        this.name = name;

        this.jedisPoolList = jedisList;

        this.cacheStoreRouter = cacheStoreRouter;

        this.serializer = serializer;

        this.expires = expires;

    }

    // 实现get、put、evict、clear;

}

 

    再次,使用方法。

@Repository

public class UserInfoDao {

 

    @Resource

    UserInfoMapper userInfoMapper;

 

    @Cacheable(value = "user_info", key = "#id")

    public UserInfo getUserInfoBySid(long id) {

        return userInfoMapper.getUserInfoBySid(id);

    }

 

    @CacheEvict(value = "user_info", key = "#userInfo.id")

    public void updateUserInfo(UserInfo userInfo) {

        userInfoMapper.update(userInfo);

    }

 

    public void insertUserInfo(UserInfo userInfo) {

        userInfoMapper.insert(userInfo);

    }

}

 

 

  最后,本周会补上实践代码到github。

     PS:本来是打算周末把redis作cache那一套自己实现了再配置的,结果其实spring-data-redis已经能

满足我的需求了。我就直接用了配置下即可: https://github.com/wdmyong/spring-cache。有时间 

我会把自己实现的一套也用一个分支推上去的。目前还只是用了下spring-data-redis,但是怎么在不用

redis-cluster的情况下配置jedispoollist,以及用int等基本类型,value对象如何不用实现序列化接口都

有待研究,有懂的也请指点一二,评论即可。

 

 

    <cache:annotation-driven /> <!-- 需要 xmlns:cache="http://www.springframework.org/schema/cache" 以及相应的location -->

 

    <!-- jedis 配置 -->  

 

   <bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">  

 

       <property name="maxIdle" value="${redis.maxIdle}" />  

 

       <!--<property name="maxWaitMillis" value="${redis.maxWait}" />-->  

 

       <property name="testOnBorrow" value="${redis.testOnBorrow}" />  

 

   </bean>  

 

 

 

    <!-- redis服务器中心 -->  

 

    <bean id="connectionFactory"  

 

        class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">

 

        <property name="poolConfig" ref="poolConfig" />

 

        <property name="port" value="${redis.port}" />

 

        <property name="hostName" value="${redis.hostname}" />

 

        <property name="timeout" value="${redis.timeout}" />

 

    </bean>  

 

 

 

    <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">

 

        <property name="connectionFactory" ref="connectionFactory" />

 

        <property name="keySerializer">

 

            <bean  

 

                class="org.springframework.data.redis.serializer.StringRedisSerializer" />

 

        </property>

 

        <property name="valueSerializer">

 

            <bean  class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer" />

 

        </property>

 

    </bean>

 

 

 

    <!-- 配置缓存 -->

 

    <bean id="cacheManager" class="org.springframework.data.redis.cache.RedisCacheManager">

 

        <constructor-arg ref="redisTemplate" />

 

    </bean>

 

posted @ 2017-04-13 01:14  鹰搏长空08  阅读(556)  评论(0编辑  收藏  举报