详解java之redis篇(spring-data-redis整合)

发布时间 - 2026-01-10 22:24:24    点击率:

1,利用spring-data-redis整合

项目使用的pom.xml:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 <modelVersion>4.0.0</modelVersion>

 <groupId>com.x.redis</groupId>
 <artifactId>Spring_redis</artifactId>
 <version>1.0-SNAPSHOT</version>
 <packaging>jar</packaging>

 <name>Spring_redis</name>
 <url>http://maven.apache.org</url>

 <properties>
 <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
 </properties>

 <dependencies>
  <dependency> 
  <groupId>org.springframework.data</groupId> 
  <artifactId>spring-data-redis</artifactId> 
  <version>1.0.2.RELEASE</version> 
 </dependency> 
 <dependency> 
  <groupId>org.springframework</groupId> 
  <artifactId>spring-core</artifactId> 
  <version>3.1.2.RELEASE</version> 
 </dependency> 

  
 <dependency> 
  <groupId>redis.clients</groupId> 
  <artifactId>jedis</artifactId> 
  <version>2.1.0</version> 
 </dependency> 
  
  <dependency> 
  <groupId>junit</groupId> 
  <artifactId>junit</artifactId> 
  <version>4.8.2</version> 
  <scope>test</scope> 
 </dependency> 
    <dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>1.6.1</version>
   </dependency>
   <!-- 将现有的jakarta commons logging的调用转换成lsf4j的调用。 -->
   <dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>jcl-over-slf4j</artifactId>
    <version>1.6.1</version>
   </dependency>
   <!-- Hack:确保commons-logging的jar包不被引入,否则将和jcl-over-slf4j冲突 -->
   <dependency>
    <groupId>commons-logging</groupId>
    <artifactId>commons-logging</artifactId>
    <version>1.1.1</version>
    <scope>provided</scope>
   </dependency>
   <!-- slf4j的实现:logback,用来取代log4j。更快、更强! -->
   <dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-classic</artifactId>
    <version>0.9.24</version>
    <scope>runtime</scope>
   </dependency>
 </dependencies>
</project>

除了log部分,只有一个spring core 和 spring-data-redis了

项目文件目录结构:

applicationContext.xml:

1,context:property-placeholder 标签用来导入properties文件。从而替换${redis.maxIdle}这样的变量。

2,context:component-scan 是为了在com.x.redis.dao报下的类能够实用spring的注解注入的方式。

3,事实上我们只需要把JedisPoolConfig配数来就好了,接下来就是spring的封装了。所以直接看UserDAOImpl的实现就明白了。

<?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:p="http://www.springframework.org/schema/p" 
 xmlns:context="http://www.springframework.org/schema/context" 
 xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx" 
 xmlns:aop="http://www.springframework.org/schema/aop" 
 xsi:schemaLocation=" 
   http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd 
   http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> 
 
 <context:property-placeholder location="classpath:redis.properties" /> 
 <context:component-scan base-package="com.x.redis.dao">
 </context:component-scan>
 <bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig"> 
  <property name="maxIdle" value="${redis.maxIdle}" /> 
  <property name="maxActive" value="${redis.maxActive}" /> 
  <property name="maxWait" value="${redis.maxWait}" /> 
  <property name="testOnBorrow" value="${redis.testOnBorrow}" /> 
 </bean> 
  
 <bean id="connectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" 
  p:host-name="${redis.host}" p:port="${redis.port}" p:password="${redis.pass}" p:pool-config-ref="poolConfig"/> 
  
 <bean id="redisTemplate" class="org.springframework.data.redis.core.StringRedisTemplate"> 
  <property name="connectionFactory" ref="connectionFactory" /> 
 </bean>   
  
 <bean id="userDAO" class="com.x.redis.dao.impl.UserDAOImpl" /> 
</beans>

redis.properties:

# Redis settings
#redis.host=192.168.20.101
#redis.port=6380
#redis.pass=foobared
redis.host=127.0.0.1
redis.port=6379
redis.pass=
 
redis.maxIdle=300
redis.maxActive=600
redis.maxWait=1000
redis.testOnBorrow=true

UserDAOImpl:

1,spring对dao层的封装很多用了类似于下面代码的模板方式。

2,RedisTemplate就是spring对redis的一个封装而已。

public class UserDAOImpl implements UserDAO {

 @Autowired
 protected RedisTemplate<Serializable, Serializable> redisTemplate;

 public void saveUser(final User user) {
  redisTemplate.execute(new RedisCallback<Object>() {

   @Override
   public Object doInRedis(RedisConnection connection) throws DataAccessException {
    connection.set(redisTemplate.getStringSerializer().serialize("user.uid." + user.getId()),
        redisTemplate.getStringSerializer().serialize(user.getName()));
    return null;
   }
  });
 }

 @Override
 public User getUser(final long id) {
  return redisTemplate.execute(new RedisCallback<User>() {
   @Override
   public User doInRedis(RedisConnection connection) throws DataAccessException {
    byte[] key = redisTemplate.getStringSerializer().serialize("user.uid." + id);
    if (connection.exists(key)) {
     byte[] value = connection.get(key);
     String name = redisTemplate.getStringSerializer().deserialize(value);
     User user = new User();
     user.setName(name);
     user.setId(id);
     return user;
    }
    return null;
   }
  });
 }

 
}

其他:

User:

public class User {

 private long id;
 private String name;
 
 public long getId() {
  return id;
 }
 
 public void setId(long id) {
  this.id = id;
 }
 
 public String getName() {
  return name;
 }
 
 public void setName(String name) {
  this.name = name;
 }
}

测试代码:

public static void main(String[] args) {
  ApplicationContext ac = new ClassPathXmlApplicationContext("classpath:/applicationContext.xml");
  UserDAO userDAO = (UserDAO)ac.getBean("userDAO");
  User user1 = new User();
  user1.setId(1);
  user1.setName("obama");
  userDAO.saveUser(user1);
  User user2 = userDAO.getUser(1);
  System.out.println(user2.getName());
 }

2,不利用spring-data-redis整合

个人觉得这样整合灵活度更大,能够更加明了的完成任务。

pom.xml:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 <modelVersion>4.0.0</modelVersion>

 <groupId>com.d.work</groupId>
 <artifactId>Redis_Templete</artifactId>
 <version>1.0-SNAPSHOT</version>
 <packaging>jar</packaging>

 <name>Redis_Templete</name>
 <url>http://maven.apache.org</url>

 <properties>
 <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
 </properties>

 <dependencies>
 <dependency>
  <groupId>junit</groupId>
  <artifactId>junit</artifactId>
  <version>3.8.1</version>
  <scope>test</scope>
 </dependency>
 <dependency> 
  <groupId>redis.clients</groupId> 
  <artifactId>jedis</artifactId> 
  <version>2.1.0</version> 
 </dependency> 
  <dependency> 
  <groupId>org.springframework</groupId> 
  <artifactId>spring-core</artifactId> 
  <version>3.1.2.RELEASE</version> 
 </dependency> 
  <dependency> 
  <groupId>org.springframework</groupId> 
  <artifactId>spring-beans</artifactId> 
  <version>3.1.2.RELEASE</version> 
 </dependency> 
  <dependency> 
  <groupId>org.springframework</groupId> 
  <artifactId>spring-context</artifactId> 
  <version>3.1.2.RELEASE</version> 
 </dependency> 
 <dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>1.6.1</version>
   </dependency>
   <!-- 将现有的jakarta commons logging的调用转换成lsf4j的调用。 -->
   <dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>jcl-over-slf4j</artifactId>
    <version>1.6.1</version>
   </dependency>
   <!-- Hack:确保commons-logging的jar包不被引入,否则将和jcl-over-slf4j冲突 -->
   <dependency>
    <groupId>commons-logging</groupId>
    <artifactId>commons-logging</artifactId>
    <version>1.1.1</version>
    <scope>provided</scope>
   </dependency>
   <!-- slf4j的实现:logback,用来取代log4j。更快、更强! -->
   <dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-classic</artifactId>
    <version>0.9.24</version>
    <scope>runtime</scope>
   </dependency>
 </dependencies>
</project>

目录结构:

data-source.xml

1,context:property-placeholder 和 context:component-scan 前面解释过啦。

2,配置了一个ShardedJedisPool,在jdeis里 还有个JedisPool。这两个的区别:

一个是分片形式,可以连接有主备的redis服务端,一个是单个的。详细后续学习

3,因为不使用spring-data-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:p="http://www.springframework.org/schema/p" 
 xmlns:context="http://www.springframework.org/schema/context" 
 xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx" 
 xmlns:aop="http://www.springframework.org/schema/aop" 
 xsi:schemaLocation=" 
   http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd 
   http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> 

 <context:property-placeholder location="classpath:redis.properties" /> 
 <context:component-scan base-package="com.d.work.main">
 </context:component-scan>
  <context:component-scan base-package="com.d.work.redis">
 </context:component-scan>
 <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
  <property name="maxActive" value="50" />
  <property name="maxIdle" value="8" />
  <property name="maxWait" value="1000" />
  <property name="testOnBorrow" value="true"/>
  <property name="testOnReturn" value="true"/>
  <!-- <property name="testWhileIdle" value="true"/> -->
 </bean>

 <bean id="shardedJedisPool" class="redis.clients.jedis.ShardedJedisPool" scope="singleton">
  <constructor-arg index="0" ref="jedisPoolConfig" />
  <constructor-arg index="1">
   <list>
    <bean class="redis.clients.jedis.JedisShardInfo">
     <constructor-arg name="host" value="${redis.host}" />
     <constructor-arg name="port" value="${redis.port}" />
     <constructor-arg name="timeout" value="${redis.timeout}" />
     <constructor-arg name="weight" value="1" />
    </bean>
   </list>
  </constructor-arg>
 </bean>
</beans>

RedisDataSource:定义三个方法

public interface RedisDataSource {
 public abstract ShardedJedis getRedisClient();
 public void returnResource(ShardedJedis shardedJedis);
 public void returnResource(ShardedJedis shardedJedis,boolean broken);
}

实现redisDataSource:

1, 注入配置好的ShardedJedisPool,这三个方法的作用:

  •  getRedisClient() : 取得redis的客户端,可以执行命令了。
  • returnResource(ShardedJedis shardedJedis) : 将资源返还给pool
  • returnResource(ShardedJedis shardedJedis, boolean broken) : 出现异常后,将资源返还给pool (其实不需要第二个方法)
@Repository("redisDataSource")
public class RedisDataSourceImpl implements RedisDataSource {

 private static final Logger log = LoggerFactory.getLogger(RedisDataSourceImpl.class);

 @Autowired
 private ShardedJedisPool shardedJedisPool;

 public ShardedJedis getRedisClient() {
  try {
   ShardedJedis shardJedis = shardedJedisPool.getResource();
   return shardJedis;
  } catch (Exception e) {
   log.error("getRedisClent error", e);
  }
  return null;
 }

 public void returnResource(ShardedJedis shardedJedis) {
  shardedJedisPool.returnResource(shardedJedis);
 }

 public void returnResource(ShardedJedis shardedJedis, boolean broken) {
  if (broken) {
   shardedJedisPool.returnBrokenResource(shardedJedis);
  } else {
   shardedJedisPool.returnResource(shardedJedis);
  }
 }
}

第二层的封装:RedisClientTemplate,例子实现了放值和取值。最后代码提供了全部命令的实现。

代码就是映射性质的又一次调用jedis的方法而已,用了个broken来做标示符,决定返还资源的方式。

这一层的目的主要也是让再上层的调用不需要关心pool中链接的取得和返还问题了。

@Repository("redisClientTemplate")
public class RedisClientTemplate {

 private static final Logger log = LoggerFactory.getLogger(RedisClientTemplate.class);

 @Autowired
 private RedisDataSource  redisDataSource;

 public void disconnect() {
  ShardedJedis shardedJedis = redisDataSource.getRedisClient();
  shardedJedis.disconnect();
 }

 /**
  * 设置单个值
  * 
  * @param key
  * @param value
  * @return
  */
 public String set(String key, String value) {
  String result = null;

  ShardedJedis shardedJedis = redisDataSource.getRedisClient();
  if (shardedJedis == null) {
   return result;
  }
  boolean broken = false;
  try {
   result = shardedJedis.set(key, value);
  } catch (Exception e) {
   log.error(e.getMessage(), e);
   broken = true;
  } finally {
   redisDataSource.returnResource(shardedJedis, broken);
  }
  return result;
 }

 /**
  * 获取单个值
  * 
  * @param key
  * @return
  */
 public String get(String key) {
  String result = null;
  ShardedJedis shardedJedis = redisDataSource.getRedisClient();
  if (shardedJedis == null) {
   return result;
  }

  boolean broken = false;
  try {
   result = shardedJedis.get(key);

  } catch (Exception e) {
   log.error(e.getMessage(), e);
   broken = true;
  } finally {
   redisDataSource.returnResource(shardedJedis, broken);
  }
  return result;
 }
}

测试代码:

 public static void main(String[] args) {
  ApplicationContext ac = new ClassPathXmlApplicationContext("classpath:/data-source.xml");
  RedisClientTemplate redisClient = (RedisClientTemplate)ac.getBean("redisClientTemplate");
  redisClient.set("a", "abc");
  System.out.println(redisClient.get("a"));
 }

附上RedisClientTemplate全部实现:

RedisClientTemplate代码太多,附上下载地址:http://xiazai./201701/yuanma/RedisClientTemplate_jb51.rar

 以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。


# spring  # 整合redis  # redis和spring整合  # 解决spring集成redisson踩过的坑  # Spring使用redis遇到的问题及解决方案  # Spring-data-redis操作redis知识总结  # 使用Spring Data Redis实现数据缓存的方法  # 解决spring data redis的那些坑  # 不需要  # 用了  # 更快  # 不被  # 更强  # 转换成  # 则将  # 这一  # 太多  # 有个  # 下载地址  # 只需  # 更大  # 要把  # 这两个  # 第二个  # 只有一个  # 来做  # 类似于  # 装了 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: b2c电商网站制作流程,b2c水平综合的电商平台?  Laravel如何使用Eloquent进行子查询  javascript基本数据类型及类型检测常用方法小结  nodejs redis 发布订阅机制封装实现方法及实例代码  文字头像制作网站推荐软件,醒图能自动配文字吗?  如何在阿里云通过域名搭建网站?  如何快速启动建站代理加盟业务?  香港服务器建站指南:免备案优势与SEO优化技巧全解析  大连网站制作公司哪家好一点,大连买房网站哪个好?  大连 网站制作,大连天途有线官网?  Laravel Eloquent访问器与修改器是什么_Laravel Accessors & Mutators数据处理技巧  宙斯浏览器文件分类查看教程 快速筛选视频文档与图片方法  Windows Hello人脸识别突然无法使用  北京专业网站制作设计师招聘,北京白云观官方网站?  千库网官网入口推荐 千库网设计创意平台入口  免费制作统计图的网站有哪些,如何看待现如今年轻人买房难的情况?  微信小程序 闭包写法详细介绍  Laravel集合Collection怎么用_Laravel集合常用函数详解  如何用搬瓦工VPS快速搭建个人网站?  详解Nginx + Tomcat 反向代理 如何在高效的在一台服务器部署多个站点  购物网站制作费用多少,开办网上购物网站,需要办理哪些手续?  图片制作网站免费软件,有没有免费的网站或软件可以将图片批量转为A4大小的pdf?  如何构建满足综合性能需求的优质建站方案?  如何基于云服务器快速搭建网站及云盘系统?  Linux后台任务运行方法_nohup与&使用技巧【技巧】  什么是javascript作用域_全局和局部作用域有什么区别?  Swift中swift中的switch 语句  Laravel如何部署到服务器_线上部署Laravel项目的完整流程与步骤  JavaScript中的标签模板是什么_它如何扩展字符串功能  html文件怎么打开证书错误_https协议的html打开提示不安全【指南】  详解jQuery中的事件  DeepSeek是免费使用的吗 DeepSeek收费模式与Pro版本功能详解  Laravel的HTTP客户端怎么用_Laravel HTTP Client发起API请求教程  网站制作大概多少钱一个,做一个平台网站大概多少钱?  Laravel怎么创建自己的包(Package)_Laravel扩展包开发入门到发布  Laravel怎么多语言本地化设置_Laravel语言包翻译与Locale动态切换【手册】  Linux系统命令中screen命令详解  如何在服务器上三步完成建站并提升流量?  深入理解Android中的xmlns:tools属性  LinuxCD持续部署教程_自动发布与回滚机制  Laravel怎么实现API接口鉴权_Laravel Sanctum令牌生成与请求验证【教程】  Laravel如何与Docker(Sail)协同开发?(环境搭建教程)  Laravel软删除怎么实现_Laravel Eloquent SoftDeletes功能使用教程  如何彻底卸载建站之星软件?  手机怎么制作网站教程步骤,手机怎么做自己的网页链接?  Laravel如何使用Blade模板引擎?(完整语法和示例)  Win11应用商店下载慢怎么办 Win11更改DNS提速下载【修复】  php读取心率传感器数据怎么弄_php获取max30100的心率值【指南】  Java类加载基本过程详细介绍  简单实现Android验证码