Spring 配置Redies缓存@Cacheable注解与 @CacheEvict注解

Posted 为乐而来

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring 配置Redies缓存@Cacheable注解与 @CacheEvict注解相关的知识,希望对你有一定的参考价值。

 

1.properties文件指定Redis连接IP与密码

# Redis IP  
redis.host=127.0.0.1
redis.port=6379
#Redis PassWord
redis.password=123
redis.timeOut=10000
# \\u5BC6\\u7801\\u7559\\u7A7A\\u5F88\\u6709\\u5FC5\\u8981(\\u8FD9\\u4E2A\\u8BBE\\u7F6E\\u4E0D\\u7528\\u4F7F\\u7528\\uFF09
redis.pass=
redis.maxTotal=200
redis.maxIdle=50
redis.minIdle=8
redis.maxWaitMillis=10000
redis.testOnBorrow=true
redis.testOnReturn=true
redis.testWhileIdle=true
redis.timeBetweenEvictionRunsMillis=30000
redis.numTestsPerEvictionRun=10
redis.minEvictableIdleTimeMillis=60000

# Redis DB(0-15)
redis.database=14

 

2.在applicationContext.xml文件添加节点:

<import resource="spring-redis.xml"/>

    <!-- 启动缓存 -->
    <cache:annotation-driven />

3.新建spring-redis.xml 文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:p="http://www.springframework.org/schema/p"
       xsi:schemaLocation="http://www.springframework.org/schema/beans 
                           http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
                           http://www.springframework.org/schema/context 
                           http://www.springframework.org/schema/context/spring-context-4.3.xsd  
                           http://www.springframework.org/schema/mvc 
                           http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd
                           http://www.springframework.org/schema/aop 
                           http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
                           http://www.springframework.org/schema/tx 
                           http://www.springframework.org/schema/tx/spring-tx-4.3.xsd"
                           default-lazy-init="true" >

    <!--redis配置  -->
    <bean name="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig" lazy-init="true">
        <property name="maxTotal" value="${redis.maxTotal}"/>
        <property name="maxIdle" value="${redis.maxIdle}"/>
        <property name="minIdle" value="${redis.minIdle}"/>
        <property name="maxWaitMillis" value="${redis.maxWaitMillis}"/>
        <property name="testOnBorrow" value="${redis.testOnBorrow}"/>
        <property name="testOnReturn" value="${redis.testOnReturn}"/>
        <property name="testWhileIdle" value="${redis.testWhileIdle}"/>
        <property name="timeBetweenEvictionRunsMillis" value="${redis.timeBetweenEvictionRunsMillis}"/>
        <property name="numTestsPerEvictionRun" value="${redis.numTestsPerEvictionRun}"/>
        <property name="minEvictableIdleTimeMillis" value="${redis.minEvictableIdleTimeMillis}"/>
    </bean>
     <!-- Jedis ConnectionFactory 数据库连接配置-->  
    <bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">  
        <property name="hostName" value="${redis.host}" />  
        <property name="port" value="${redis.port}" />
        <property name="password" value="${redis.password}" />
        <property name="database" value="${redis.database}" />
        <property name="poolConfig" ref="jedisPoolConfig" />
    </bean>

    <!--  StringRedisTemplate 序列化方式  -->
    <bean id="redisTemplate" class="org.springframework.data.redis.core.StringRedisTemplate"   p:connection-factory-ref="jedisConnectionFactory" >
        <!--以String类型的方式 序列化    时间:2020年2月13日17:29:41   作者:陈翔宇  start        -->
        <property name="keySerializer">
            <bean class="org.springframework.data.redis.serializer.StringRedisSerializer" />
        </property>
        <property name="valueSerializer">
            <bean class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer" />
        </property>
        <property name="hashKeySerializer">
            <bean class="org.springframework.data.redis.serializer.StringRedisSerializer" />
        </property>
        <property name="hashValueSerializer">
            <bean class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer" />
        </property>
        <!--以String类型的方式 序列化    时间:2020年2月13日17:29:41   作者:陈翔宇  end        -->
    </bean>

    <!-- 设置Cookie domain 和 名称  -->
    <bean id="defaultCookieSerializer" class="com.kintech.web.CookieSerializer">
        <property name="domainName" value="${sysHost}"/>
        <property name="cookieName" value="MYJSESSIONID"/>
        <!--<property name="domainNamePattern" value="^.+?\\\\.(\\\\w+\\\\.[a-z]+)$"/>-->
    </bean>

    <!-- 将session放入redis -->
    <bean id="redisHttpSessionConfiguration"
         class="org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration">
        <!--session 自动超时时间-->
        <property name="maxInactiveIntervalInSeconds" value="7200" />
        <property name="cookieSerializer" ref="defaultCookieSerializer"/>

        <!--    session 创建/失效监听器   start        -->
        <property name="httpSessionListeners">
            <list>
                <bean class="com.kintech.webSYS.listener.RedisSessionListener" />
            </list>
        </property>
        <!--    session 创建/失效监听器       -->
    </bean>

    <!--@Cacheable使用Redis缓存 :  spring自己的缓存管理器,这里定义了缓存位置名称 ,即注解中的value  -->
    <bean id="cacheManager" class="org.springframework.cache.support.SimpleCacheManager">
        <property name="caches">
            <set>
                <bean class="org.springframework.data.redis.cache.RedisCache">
                    <constructor-arg name="redisOperations" ref="redisTemplate"></constructor-arg>
                    <constructor-arg name="name" value="menuAllList"></constructor-arg>
                    <constructor-arg name="prefix" value="dbSYS:"></constructor-arg>
                    <constructor-arg name="expiration" value="7200"></constructor-arg>
                </bean>
                <!-- 如果有多个缓存在这里添加多个bean menuAllList为缓存变量名称-->
            </set>
        </property>
    </bean>
    
</beans>

4.@Cacheable注解时会报错说没有key报错java.lang.ClassCastException: org.springframework.cache.interceptor.SimpleKey cannot be cast to java.lang.String,解决办法:新建文件RedisConfig.java 文件,内容如下:

@Configuration
@EnableCaching
public class RedisConfig extends CachingConfigurerSupport {
    @Override
    @Bean
    public KeyGenerator keyGenerator() {
        return (target, method, params) -> {
            StringBuilder sb = new StringBuilder();
            sb.append(target.getClass().getName());
            sb.append(method.getName());
            for (Object obj : params) {
                sb.append(obj.toString());
            }
            return sb.toString();
        };
    }
}

5.新建一个interface CacheService.java

public interface CacheService {


    List<SysMenu> findMenuAllList();//获取并缓存 menuAllList
    void clearMenuAllList();//清除menuAllList
}

6.新建class  CacheServiceImpl.java

/**
 * 缓存类
 * 该类针对一个数据表缓存只有二个方法,即一个获取缓存,一个清空缓存,
 * 获取所有缓存方法名规则 findXXXAllList()
 * 一个清空缓存方法名规则 clearXXXAllList() ,请在修改或新增该缓存表的Controller里调用一下该方法
 * 如有其他需要用的缓存的逻辑请放到该表的ServiceImple里面实现,方法名规则:findXXXFromCache()
 */
@Service("cacheService")
public class CacheServiceImpl implements CacheService {

    @Autowired
    SysMenuService sysMenuService;


    /**
     * 获取所有数据并存入缓存中
     * @return
     */
    @Override
    @Cacheable(value="menuAllList")
    public List<SysMenu> findMenuAllList() {
        return sysMenuService.findAllList();
    }
    /**
     * 清空缓存数据 (在修改或新增该表的数据时(如Controller里调用一下该方法))
     * @return
     */
    @Override
    @CacheEvict(value="menuAllList",allEntries=true)
    public void clearMenuAllList(){}
}

 

7.在Service使用缓存


@Autowired
CacheService cacheService;

/**
* 从缓存中根据Url 查数据 * @param MenuUrl * @return */ @Override public SysMenu findByMenuUrlFromCache(String MenuUrl) { List<SysMenu> listAll=cacheService.findMenuAllList(); List<SysMenu> filterList = listAll.stream().filter(item -> item.getMenuUrl().equals(MenuUrl)).collect(Collectors.toList()); if(filterList!=null && filterList.size()>0){ return filterList.get(0); }else{ return null; } }

调用以后用Redis Desktop Manager查看数据已缓存起来

 

 

也可以直接在别的地方用缓存

@Autowired
CacheService cacheService;

List<SysMenu> listAll=cacheService.findMenuAllList();

以上是关于Spring 配置Redies缓存@Cacheable注解与 @CacheEvict注解的主要内容,如果未能解决你的问题,请参考以下文章

Hibernate缓存总结

Memcached的原理分析与配置

Ubuntun安装Redies内存数据库

操作REDIES

spring 缓存(入门)

Spring缓存机制----EhCache缓存实现的配置