redis缓存集成

本文介绍如何在 Spring 4.2 中配置 Redis 作为缓存,并通过注解实现缓存操作。包括配置文件详解、依赖 JAR 包及伪代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

redis 依赖的jar包:
commons-pool2-2.5.0.jar
jedis-2.9.0.jar
spring-data-redis-1.6.2.RELEASE.jar
我是配合spring4.2实现的缓存操作:我这里实现redis唯一缓存注解实现,redis的配置加载spring里进行配置;配置内容:


spring配置:
<?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:aop="http://www.springframework.org/schema/aop" 
       xmlns:tx="http://www.springframework.org/schema/tx" 
       xmlns:task="http://www.springframework.org/schema/task" 
       xmlns:cache="http://www.springframework.org/schema/cache"
       xsi:schemaLocation="
           http://www.springframework.org/schema/beans  http://www.springframework.org/schema/beans/spring-beans-4.2.xsd  
           http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd 
           http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd  
           http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.2.xsd
           http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-4.2.xsd
           http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache-4.2.xsd">
<!-- 配置自动识别注解 -->
    <context:component-scan base-package="com.dome" >
<context:include-filter type="annotation" expression="org.springframework.stereotype.Service"/>
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>

<!-- <task:annotation-driven/> -->
    <task:annotation-driven executor="asyncExecutor" scheduler="scheduler"/>
  <task:executor id="asyncExecutor" pool-size="100-1000" queue-capacity="10000" rejection-policy="CALLER_RUNS"/>
  <task:scheduler id="scheduler" pool-size="100" />


    <!--加载数据库配置文件-->
    <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
      <property name="locations">
           <list>
              <!-- 加载数据库连接设置 -->
  <value>classpath:config/database.properties</value>
  <!-- <value>classpath:config/database.properties</value> -->
  <!-- 加载redis连接设置 -->
  <value>classpath:config/redis.properties</value>
          </list>
      </property>
    </bean>
    
<!-- 数据中心连接  就是数据库连接设置 我是封装在一个文件里的  暂不提供-->   
<import resource="datasource-sqlserver.xml" /> 
<!-- redis 缓存设置 redis 连接设置 封装在一个文件里 -->
<import resource="redisConfig.xml" />
<!-- 解决使用@ResponseBody 的中文乱码。 --> 
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">  
        <property name="messageConverters">  
            <list>  
                <!-- JSON解析对象 -->
                <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter" >
                <property name="supportedMediaTypes">
<list>
<value>application/json;charset=UTF-8</value>
</list>
</property>
                </bean>  
                <bean class="org.springframework.http.converter.StringHttpMessageConverter">  
                    <property name="supportedMediaTypes">  
                        <list>  
                            <value>text/plain;charset=UTF-8</value>  
                        </list>  
                    </property>  
                </bean>  
            </list>  
        </property>
         <!-- 日期格式转换 -->
    <property name="webBindingInitializer">    
        <bean class="com.dome.filter.DateConverterFilter" />    
    </property>    
    </bean>
 
  <bean id="captchaProducer" class="com.google.code.kaptcha.impl.DefaultKaptcha">  
  <!-- 验证码  kaptcha-->
        <property name="config">  
            <bean class="com.google.code.kaptcha.util.Config">  
                <constructor-arg>  
                    <props>  
                        <prop key="kaptcha.border">yes</prop>  
                        <prop key="kaptcha.border.color">105,179,90</prop>  
                        <prop key="kaptcha.textproducer.font.color">blue</prop>  
                        <prop key="kaptcha.image.width">125</prop>  
                        <prop key="kaptcha.image.height">45</prop>  
                        <prop key="kaptcha.textproducer.font.size">45</prop>  
                        <prop key="kaptcha.session.key">kaptchaRemote</prop>  
                        <prop key="kaptcha.textproducer.char.length">4</prop>  
                        <prop key="kaptcha.textproducer.font.names">宋体,楷体,微软雅黑</prop>  
                    </props>  
                </constructor-arg>  
            </bean>  
        </property>  
    </bean>  
</beans>


mybatisConfig.xml:redis 缓存配置


<?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:aop="http://www.springframework.org/schema/aop" 
       xmlns:tx="http://www.springframework.org/schema/tx" 
       xmlns:task="http://www.springframework.org/schema/task" 
       xmlns:cache="http://www.springframework.org/schema/cache"
       xsi:schemaLocation="
           http://www.springframework.org/schema/beans  http://www.springframework.org/schema/beans/spring-beans-4.2.xsd  
           http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd 
           http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd  
           http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.2.xsd
           http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-4.2.xsd
           http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache-4.2.xsd">


    <!-- * 优势:简单直观,效率高
         * 劣势:系统中只能用Redis一种缓存了 
                               使用redis内置CacheManager-->
         
<!-- jedis 配置  连接池配置-->
<bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">
     <!-- #最大空闲数   -->
<property name="maxIdle" value="${redis.maxIdle}" />
<!-- #控制一个pool可分配多少个jedis实例 -->
<property name="maxTotal" value="${redis.maxTotal}" />  
<!-- #最大建立连接等待时间。如果超过此时间将接到异常。设为-1表示无限制。 -->
<property name="maxWaitMillis" value="${redis.maxWaitMillis}" />
<!-- #是否在从池中取出连接前进行检验,如果检验失败,则从池中去除连接并尝试取出另一个 -->
<property name="testOnBorrow" value="${redis.testOnBorrow}" />
</bean>
 
<!-- redis服务器中心  连接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.host}" />
<property name="password" value="${redis.password}" />
<!-- #客户端超时时间单位是毫秒 默认是2000 -->
<property name="timeout" value="${redis.timeout}"></property>
<!-- #选择redis第几个库 -->
<property name="database" value="${redis.database}" />
</bean>
 
<!-- redis template,被后面的RedisCacheManager或RedisCache引用 --> 
<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
<property name="connectionFactory" ref="connectionFactory" />
  <!--开启事务  -->  
          <property name="enableTransactionSupport" value="true"/>
          <!--value,key值 的序列化  Redis缓存对象乱码处理-->
  <property name="keySerializer">
            <bean class="org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer" />
          </property>
         <property name="valueSerializer">
            <bean class="org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer" />
         </property>
         <property name="hashKeySerializer">
            <bean class="org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer" />
         </property>
         <property name="hashValueSerializer">
            <bean class="org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer" />
         </property>
         <property name="stringSerializer">
            <bean class="org.springframework.data.redis.serializer.StringRedisSerializer" />
         </property>
</bean>
<!-- 配置缓存 -->
<!-- 允许基于注解的使用,proxy-target-class默认为false,即使用JDK Proxy机制,如设置为true则基于CGLIB动态生成代理类 --> 
<cache:annotation-driven cache-manager="cacheManager" proxy-target-class="true"/>
<bean id="cacheManager" class="org.springframework.data.redis.cache.RedisCacheManager">
     <property name="usePrefix" value="true" /> 
         <property name="defaultExpiration" value="3600"/>
     <constructor-arg ref="redisTemplate" />
     <!-- 下面列表每一项对应一个Cache对象的名字,也就是@Cacheable的value指向的值-->  
         <constructor-arg>  
          <list>  
             <value>default</value><!-- 缓存名,在注解中用value引用 -->  
             <value>user</value><!-- 可以配置多个缓存,以实现不同的超时策略 --> 
             <value>test</value> 
          </list>  
        </constructor-arg>  
        <!-- 用expires属性分别配置其超时时间,缺省则使用defaultExpiration,单位均为秒 -->  
        <property name="expires">  
          <map>  
              <entry key="user" value="600"/><!-- value="0"此缓存永不超时,即使Redis重启也不会丢失哟 -->  
              <entry key="test" value="600"/><!-- value="0"此缓存永不超时,即使Redis重启也不会丢失哟 -->  
          </map>  
        </property> 
</bean>
</beans>

伪代码验证 按自己需求添加代码 (谨做参考):
伪代码:
package com.dome.service.user.impl;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import com.dome.bean.user.User;
import com.dome.dao.source2.user.UserMapper;
import com.dome.service.user.UserService;

@Service
public class UserServiceImpl implements UserService {
/**
* userService

* 缓存机制说明:所有的查询结果都放进了缓存,也就是把MySQL查询的结果放到了redis中去,
* 然后第二次发起该条查询时就可以从redis中去读取查询的结果,从而不与MySQL交互,从而达到优化的效果,
* redis的查询速度之于MySQL的查询速度相当于 内存读写速度/硬盘读写速度
* @Cacheable("a")注解的意义就是把该方法的查询结果放到redis中去,
* 下一次再发起查询就去redis中去取,存在redis中的数据的key就是a;
* @CacheEvict(value={"a","b"},allEntries=true)
* 的意思就是执行该方法后要清除redis中key名称为a,b的数据;
* key 命名规范
* 当前被调用的方法使用的Cache:#root.caches[0].name
* 当前方法名#root.methodName  当前方法#root.method.name 当前被调用的对象#root.target 当前被调用的对象的     * class#root.targetClass
* 当前方法参数组成的数组#root.args[0] 当前被调用的方法使用的Cache#root.caches[0].name */
@Autowired
private UserMapper userMapper;
@Cacheable(value="user",key="'test'")
@Override
public User selectOne(String id) {
return userMapper.selectOne(id);
}
        //allEntries=true  redis自带缓存 不能生效 要报错 我这里没有添加  
    //去除缓存
@CacheEvict(value="user",key="'test'")
@Override
public Boolean updateOne(String id) {
try {
User u = userMapper.selectOne(id);
u.setId("1");
u.setUsername("qwer1234");
userMapper.updateByPrimaryKeySelective(u);
return true;
}catch (Exception e) {
e.printStackTrace();
}
return false;
}
}

缺点:
缓存的value,key都在service层的注解里 不便于后期维护
redis缓存容易出现更新和查询缓存同步执行 出现脏数据的问题
项目中不建议这样使用 怎么写后面会有介绍---------我们先了解 在优化


这样的独占redis 的缓存 本人觉得难用 项目中 不建议这样实现 只用redis缓存配置 其他缓存需要关闭 如mybatis自带的缓存 且需添加<cache:annotation-driven cache-manager="cacheManager" proxy-target-class="true"/>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Ctrl+C+V程序猿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值