【redis】3.Spring 集成注解 redis 项目配置使用

简介: spring-data-redis  项目,配合 spring 特性并集成 Jedis 的一些命令和方法。配置redis继承到spring管理项目,使用注解实现redis缓存功能。参考:http://www.

spring-data-redis  项目,配合 spring 特性并集成 Jedis 的一些命令和方法。

配置redis继承到spring管理项目,使用注解实现redis缓存功能。

参考:http://www.cnblogs.com/java-class/p/7112541.html

 

步骤:1.maven的pom.xml文件导入架包

   2.配置文件添加配置

   3.spring管理bean的生成,xml文件配置

   4. RedisCacheConfig redis自定义的工具类,自定义redis的key生成规则

   5.在你想要做缓存的地方,使用注解进行缓存

 

 

1.maven的pom.xml文件导入架包【本来spring-data-redis架包版本使用最新的2.0.0 ,甚至使用到1.8.4版本,只要保存,启动项目,spring管理的bean都会创建失败,架包冲突的缘故或者其他问题,所以退而求其次,使用1.6.2版本】

<!-- redis架包 -->
          <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-redis</artifactId>
            <version>1.6.2.RELEASE</version>
          </dependency>
        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
            <version>2.9.0</version>
        </dependency>

 

2.配置文件添加配置

#============================#
#==== Redis settings ====#
#============================#
#redis 服务器 IP
redis.host=127.0.0.1

#redis 服务器端口
redis.port=6379

#redis 密码
redis.pass=398023

#redis 支持16个数据库(相当于不同用户)可以使不同的应用程序数据彼此分开同时又存储在相同的实例上
redis.dbIndex=0

#redis 缓存数据过期时间单位秒
redis.expiration=3000

#控制一个 pool 最多有多少个状态为 idle 的jedis实例
redis.maxIdle=300

#控制一个 pool 可分配多少个jedis实例
redis.maxActive=600

#当borrow一个jedis实例时,最大的等待时间,如果超过等待时间,则直接抛出JedisConnectionException;
redis.maxWait=1000

#在borrow一个jedis实例时,是否提前进行alidate操作;如果为true,则得到的jedis实例均是可用的;
redis.testOnBorrow=true

 

3.spring管理bean的生成,xml文件配置

 
    <!-- **************************************************redis********************************************************** -->
    <!-- 配置 JedisPoolConfig 实例 -->
    <bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">
        <property name="maxIdle" value="${redis.maxIdle}"/>
        <property name="maxTotal" value="${redis.maxActive}"/>
        <property name="maxWaitMillis" value="${redis.maxWait}"/>
        <property name="testOnBorrow" value="${redis.testOnBorrow}"/>
    </bean>

    <!-- 配置JedisConnectionFactory -->
    <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.pass}"/>
        <property name="database" value="${redis.dbIndex}"/>
        <property name="poolConfig" ref="poolConfig"/>
    </bean>

    <!-- 配置RedisTemplate -->
    <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
        <property name="connectionFactory" ref="jedisConnectionFactory"/>
    </bean>

    <!-- 配置RedisCacheManager -->
    <bean id="redisCacheManager" class="org.springframework.data.redis.cache.RedisCacheManager">
        <constructor-arg name="redisOperations" ref="redisTemplate"/>
        <property name="defaultExpiration" value="${redis.expiration}"/>
    </bean>

    <!-- 配置RedisCacheConfig -->
    <bean id="redisCacheConfig" class="com.sxd.util.RedisCacheConfig">
        <constructor-arg ref="jedisConnectionFactory"/>
        <constructor-arg ref="redisTemplate"/>
        <constructor-arg ref="redisCacheManager"/>
    </bean>

JedisPoolConfig           jedis连接池配置对象

JedisConnectionFactory         jedis连接工厂,生成连接对象

RedisTemplate          RedisTemplate 对 RedisConnection 进行了封装。提供连接管理,序列化等功能,它对 Redis 的交互进行了更高层次的抽象,极大的方便和简化了 Redis 的操作

RedisCacheManager        做为 redis 统一的调度和管理者

RedisCacheConfig         RedisCacheConfig extends org.springframework.cache.annotation.CachingConfigurerSupport,自定义redis的key生成规则,如果不在注解参数中注明key=“”的话,就采用这个类中的key生成规则生成key

 

4. RedisCacheConfig redis自定义的工具类,自定义redis的key生成规则

package com.sxd.util;

import java.lang.reflect.Method;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;

@Configuration
@EnableCaching
public class RedisCacheConfig extends CachingConfigurerSupport {
     protected final static Logger log = LoggerFactory.getLogger(RedisCacheConfig.class);

        private volatile JedisConnectionFactory mJedisConnectionFactory;
        private volatile RedisTemplate<String, String> mRedisTemplate;
        private volatile RedisCacheManager mRedisCacheManager;

        public RedisCacheConfig() {
            super();
        }

        public RedisCacheConfig(JedisConnectionFactory mJedisConnectionFactory, RedisTemplate<String, String> mRedisTemplate, RedisCacheManager mRedisCacheManager) {
            super();
            this.mJedisConnectionFactory = mJedisConnectionFactory;
            this.mRedisTemplate = mRedisTemplate;
            this.mRedisCacheManager = mRedisCacheManager;
        }

        public JedisConnectionFactory redisConnectionFactory() {
            return mJedisConnectionFactory;
        }

        public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory cf) {
            return mRedisTemplate;
        }

        public CacheManager cacheManager(RedisTemplate<?, ?> redisTemplate) {
            return mRedisCacheManager;
        }

        
        
        @Bean
        public KeyGenerator keyGenerator() {
            return new KeyGenerator() {
                @Override
                public Object generate(Object target, Method method,
                        Object... params) {
                    //规定  本类名+方法名+参数名 为key
                    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.在你想要做缓存的地方,使用注解进行缓存

先介绍几个注解

  1》@CacheConfig  配置在类上,cacheNames即定义了本类中所有用到缓存的地方,都去找这个库。只要使用了这个注解,在方法上@Cacheable    @CachePut   @CacheEvict就可以不用写value去找具体库名了。【一般不怎么用】

  2》@Cacheable  配置在方法或类上,作用:本方法执行后,先去缓存看有没有数据,如果没有,从数据库中查找出来,给缓存中存一份,返回结果,下次本方法执行,在缓存未过期情况下,先在缓存中查找,有的话直接返回,没有的话从数据库查找

  3》@CachePut   类似于更新操作,即每次不管缓存中有没有结果,都从数据库查找结果,并将结果更新到缓存,并返回结果

  4》@CacheEvict 用来清除用在本方法或者类上的缓存数据(用在哪里清除哪里)

例子:

最直观的表现:首次登录,会有一条数据库的查询语句在控制台。

       退出再登录,不会执行数据库的查询,直接从数据库中取出缓存,登录成功。

说明:

  ①使用了@Cacheable(value="myUser"),即表示缓存中有,直接从缓存取出,没有的话先从数据库中查出,然后再插入

  ②如果未在类上使用@CacheConfig注解规定数据要缓存到哪个库中,就必须给value一个值,规定数据最后缓存到哪个redis库中

  ③因为redis缓存数据实际就是键值对的形式存储,因此必须给定key-value的key,这里没有给key参数赋值,所以key的生成规则按照上面工具类中规定的key生成的

  ④key-value的value就是本方法的返回值,如果要缓存登录用户信息,本方法需要进行修改,返回user对象就可以缓存到key-value的value中

 

*******************************************************************************************************************************************************************

*******************************************************************************************************************************************************************

查看一下本次缓存的数据,在redis可视化工具中

myUser是上面注解中的value,也就是缓存数据库名字叫myUser

键名key为:\xAC\xED\x00\x05t\x00Jcom.sxd.controller.WelcomeController_welcome_com.sxd.entity.User@36e69d03,

键值对value值:\xAC\xED\x00\x05t\x00\x07success

   ①redis以键值对的形式存储缓存数据,而且会对对象进行序列化,如上图可以看到,键和值前面都有一串序列化的字符

   ② RedisTemplate默认采用的是JDK的序列化策略,保存的key和value都是采用此策略序列化保存的。JdkSerializationRedisSerializer

   ③SDR默认采用的序列化策略有两种,一种是String的序列化策略,一种是JDK的序列化策略。

        StringRedisTemplate默认采用的是String的序列化策略,保存的key和value都是采用此策略序列化保存的。StringRedisSerializer

        RedisTemplate默认采用的是JDK的序列化策略,保存的key和value都是采用此策略序列化保存的。JdkSerializationRedisSerializer

   就是因为序列化策略的不同,即使是同一个key用不同的Template去序列化,结果是不同的。所以根据key去删除数据的时候就出现了删除失败的问题。

   ④在上面配置文件中,没有显式的给出序列化策略,会有默认的序列化策略。

   ⑤如果因为序列化策略不同,可以区显式的设置  具体可参考:http://blog.csdn.net/y666666y/article/details/70212767

<!-- redis 序列化策略 ,通常情况下key值采用String序列化策略, -->  
<!-- 如果不指定序列化策略,StringRedisTemplate的key和value都将采用String序列化策略; -->  
<!-- 但是RedisTemplate的key和value都将采用JDK序列化 这样就会出现采用不同template保存的数据不能用同一个template删除的问题 -->  
<bean id="stringRedisSerializer"   
    class="org.springframework.data.redis.serializer.StringRedisSerializer" />  
  
<bean id='redisWriteTemplate' class="org.springframework.data.redis.core.RedisTemplate">  
    <property name="connectionFactory" ref="jedisWriteConnectionFactory" />  
    <property name="keySerializer" ref="stringRedisSerializer" />  
    <property name="hashKeySerializer" ref="stringRedisSerializer" />  
</bean>

   

 

*************************************************************************************************************************************************************************************

*************************************************************************************************************************************************************************************

最后给出这几个注解的具体参数以及使用相关配图参考。

参考自:http://blog.csdn.net/sanjay_f/article/details/47372967

 

表 1. @Cacheable 作用和配置方法

@Cacheable 的作用 主要针对方法配置,能够根据方法的请求参数对其结果进行缓存

@Cacheable 主要的参数
value 缓存的名称,缓存中具体哪个数据库,在 spring 配置文件中定义,必须指定至少一个 例如:
@Cacheable(value=”mycache”) 或者 
@Cacheable(value={”cache1”,”cache2”}
key 缓存的 key,可以为空,如果指定要按照 SpEL 表达式编写,如果不指定,则缺省按照方法的所有参数进行组合,或者方法参数列表中的任意一个参数,或者字符串+参数组合

例如:
@Cacheable(value=”testcache”,key=”#userName”)

@Cacheable(value=”testcache”,key=” '字符串'+#userName”)

condition 缓存的条件,可以为空,使用 SpEL 编写,返回 true 或者 false,只有为 true 才进行缓存 例如:
@Cacheable(value=”testcache”,condition=”#userName.length()>2”)
 
表 2. @CachePut 作用和配置方法
@CachePut 的作用 主要针对方法配置,能够根据方法的请求参数对其结果进行缓存,和 @Cacheable 不同的是,它每次都会触发真实方法的调用
@CachePut 主要的参数
value 缓存的名称,在 spring 配置文件中定义,必须指定至少一个 例如:
@Cacheable(value=”mycache”) 或者 
@Cacheable(value={”cache1”,”cache2”}
key 缓存的 key,可以为空,如果指定要按照 SpEL 表达式编写,如果不指定,则缺省按照方法的所有参数进行组合 例如:
@Cacheable(value=”testcache”,key=”#userName”)
condition 缓存的条件,可以为空,使用 SpEL 编写,返回 true 或者 false,只有为 true 才进行缓存 例如:
@Cacheable(value=”testcache”,condition=”#userName.length()>2”)
 
表 3. @CacheEvict 作用和配置方法
@CachEvict 的作用 主要针对方法配置,能够根据一定的条件对缓存进行清空
@CacheEvict 主要的参数
value 缓存的名称,在 spring 配置文件中定义,必须指定至少一个 例如:
@CachEvict(value=”mycache”) 或者 
@CachEvict(value={”cache1”,”cache2”}
key 缓存的 key,可以为空,如果指定要按照 SpEL 表达式编写,如果不指定,则缺省按照方法的所有参数进行组合 例如:
@CachEvict(value=”testcache”,key=”#userName”)
condition 缓存的条件,可以为空,使用 SpEL 编写,返回 true 或者 false,只有为 true 才清空缓存 例如:
@CachEvict(value=”testcache”,
condition=”#userName.length()>2”)
allEntries 是否清空所有缓存内容,缺省为 false,如果指定为 true,则方法调用后将立即清空所有缓存 例如:
@CachEvict(value=”testcache”,allEntries=true)
beforeInvocation 是否在方法执行前就清空,缺省为 false,如果指定为 true,则在方法还没有执行的时候就清空缓存,缺省情况下,如果方法执行抛出异常,则不会清空缓存 例如:
@CachEvict(value=”testcache”,beforeInvocation=true)

 

*************************************************************************************************************************************************************************************

*************************************************************************************************************************************************************************************

spEL表达式的使用方法:http://docs.spring.io/spring/docs/4.2.x/spring-framework-reference/html/expressions.html

关于注解实现Redis缓存的方法,只有将key设计的合理且强大,整个的缓存在项目中才能通用且高效。否则,就像我上面的简单的例子一样,真的是搞笑了。

 

相关文章
|
6月前
|
缓存 负载均衡 监控
135_负载均衡:Redis缓存 - 提高缓存命中率的配置与最佳实践
在现代大型语言模型(LLM)部署架构中,缓存系统扮演着至关重要的角色。随着LLM应用规模的不断扩大和用户需求的持续增长,如何构建高效、可靠的缓存架构成为系统性能优化的核心挑战。Redis作为业界领先的内存数据库,因其高性能、丰富的数据结构和灵活的配置选项,已成为LLM部署中首选的缓存解决方案。
668 25
|
7月前
|
传感器 Java 数据库
探索Spring Boot的@Conditional注解的上下文配置
Spring Boot 的 `@Conditional` 注解可根据不同条件动态控制 Bean 的加载,提升应用的灵活性与可配置性。本文深入解析其用法与优势,并结合实例展示如何通过自定义条件类实现环境适配的智能配置。
391 0
探索Spring Boot的@Conditional注解的上下文配置
|
9月前
|
Java 关系型数据库 数据库连接
Spring Boot项目集成MyBatis Plus操作PostgreSQL全解析
集成 Spring Boot、PostgreSQL 和 MyBatis Plus 的步骤与 MyBatis 类似,只不过在 MyBatis Plus 中提供了更多的便利功能,如自动生成 SQL、分页查询、Wrapper 查询等。
924 3
|
9月前
|
NoSQL 安全 Linux
设置Redis在CentOS7上的自启动配置
这些步骤总结了在CentOS 7系统上设置Redis服务自启动的过程。这些命令提供了一个直接且明了的方式,确保Redis作为关键组件在系统启动时能自动运行,保障了依赖于Redis服务的应用的稳定性和可用性。
699 9
|
9月前
|
存储 缓存 NoSQL
Redis 核心知识与项目实践解析
本文围绕 Redis 展开,涵盖其在项目中的应用(热点数据缓存、存储业务数据、实现分布式锁)、基础数据类型(string 等 5 种)、持久化策略(RDB、AOF 及混合持久化)、过期策略(惰性 + 定期删除)、淘汰策略(8 种分类)。 还介绍了集群方案(主从复制、哨兵、Cluster 分片)及主从同步机制,分片集群数据存储的哈希槽算法。对比了 Redis 与 Memcached 的区别,说明了内存用完的情况及与 MySQL 数据一致性的保证方案。 此外,详解了缓存穿透、击穿、雪崩的概念及解决办法,如何保证 Redis 中是热点数据,Redis 分布式锁的实现及问题解决,以及项目中分布式锁
261 1
|
9月前
|
前端开发 Java API
酒店管理系统基于 JavaFX Spring Boot 和 React 经典项目重构实操
本文介绍了基于现代技术栈的酒店管理系统开发方案,整合了JavaFX、Spring Boot和React三大技术框架。系统采用前后端分离架构,JavaFX构建桌面客户端,React开发Web管理界面,Spring Boot提供RESTful API后端服务。核心功能模块包括客房管理和客户预订流程,文中提供了JavaFX实现的客房管理界面代码示例和React开发的预订组件代码,展示了如何实现客房信息展示、添加修改操作以及在线预订功能。
606 0
|
9月前
|
Java 测试技术 Spring
简单学Spring Boot | 博客项目的测试
本内容介绍了基于Spring Boot的博客项目测试实践,重点在于通过测试驱动开发(TDD)优化服务层代码,提升代码质量和功能可靠性。案例详细展示了如何为PostService类编写测试用例、运行测试并根据反馈优化功能代码,包括两次优化过程。通过TDD流程,确保每项功能经过严格验证,增强代码可维护性与系统稳定性。
353 0
|
9月前
|
存储 Java 数据库连接
简单学Spring Boot | 博客项目的三层架构重构
本案例通过采用三层架构(数据访问层、业务逻辑层、表现层)重构项目,解决了集中式开发导致的代码臃肿问题。各层职责清晰,结合依赖注入实现解耦,提升了系统的可维护性、可测试性和可扩展性,为后续接入真实数据库奠定基础。
711 0
|
9月前
|
Java 应用服务中间件 Maven
第01课:Spring Boot开发环境搭建和项目启动
第01课:Spring Boot开发环境搭建和项目启动
2690 0
下一篇
开通oss服务