spring自定义cache

下面是一个较为详细的spring缓存的介绍

http://www.ibm.com/developerworks/cn/opensource/os-cn-spring-cache/

 

Cacheable注解,是spring支持的一个注解,用法就不多说了,但是发现了一个奇怪的用法,Cacheable的value属性官方定义为缓存的名字,但是在这里却被当成了缓存的失效时长。

    /**
     * http请求获取城市列表
     */
    @Override
    @Cacheable(value = "86400", key = "'***_city_list'")
    public CityListModel getCities() {
        String cities;
    ......
    }

 

 

 

这就需要研究下自定义spring缓存的步骤

1.自定义CacheManager

2.自定义Cache

其中CacheManager.getCache方法的入参的含义是缓存的名字,就是Cacheable注解的value值,接下来思路就清晰了,通过获取getCache(String name)的name(实际上是超时时间)对缓存的操作,就实现了上面的功能。

 

package org.springframework.cache;
public interface CacheManager {
	/**
	 * Return the cache associated with the given name.
	 * @param name the cache identifier (must not be {@code null})
	 * @return the associated cache, or {@code null} if none found
	 */
	Cache getCache(String name);

	/**
	 * Return a collection of the cache names known by this manager.
	 * @return the names of all caches known by the cache manager
	 */
	Collection<String> getCacheNames();
}

 

 

package org.springframework.cache;
public interface Cache {...}

 

 

 

下面是CacheManager的实现类,根据一个ConcurrentMap(key超时时间,value对应相应的缓存),MedisConcurrentCache封装了缓存的超时操作,用一种很巧妙的方式给Cacheable增加了超时的功能。

 

public class MedisConcurrentCacheManager extends AbstractConcurrentCacheManager implements InitializingBean {
    private static final Logger LOGGER = LoggerFactory.getLogger(MedisConcurrentCacheManager.class);

    private MedisConcurrentCache cache;
    private String nameSpace;
    private IMedis meids;
    private ConcurrentMap<Integer, MedisConcurrentCache> cachedCaches = Maps.newConcurrentMap();

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

    @Override
    public Cache getCache(String expire) {
        try {
            if (StringUtils.isBlank(expire)) {
                return cache;
            }
            for (char c : expire.toCharArray()) {
                if (!Character.isDigit(c)) {
                    return cache;
                }
            }
            int expireInt = Integer.valueOf(expire);
            MedisConcurrentCache cache = cachedCaches.get(expireInt);
            if (null == cache) {
                cache = new MedisConcurrentCache();
                cache.setExpireTime(expireInt);
                cache.setMedis(meids);
                cache.setNameSpace(nameSpace);
                cachedCaches.putIfAbsent(expireInt, cache);
                cache = cachedCaches.get(expireInt);
            }
            return cache;
        } catch (Exception e) {
            LOGGER.error(e.getMessage(), e);
        }
        return cache;
    }
。。。。。。
}

 

 

 

下面是spring的配置

 

<bean id="cacheManager"
      class="com.meituan.service.mobile.movie.cache.impl.MedisConcurrentCacheManager">
    <property name="cache" ref="cache"/>
</bean>

<cache:annotation-driven cache-manager="cacheManager" proxy-target-class="true"/>

<import resource="classpath:rediscloud-auth-test.xml"/>

<bean id="cache"
      class="com.meituan.service.mobile.movie.cache.impl.MedisConcurrentCache">
    <property name="medis" ref="medis"/>
    <property name="nameSpace" value="apollosupplier:"/>
</bean>

<bean id="medis"
      class="com.meituan.cache.redisCluster.client.MedisBean">
    <property name="authDao" ref="zkAuthDao"/>
    <property name="poolId" value="mobile-apollo-item-cache01"/>
    <property name="authKey" value="gE9rVsIOG2Rh5y2dcAOW"/>
</bean>

 

你可能感兴趣的:(java,spring,cache)