spring整合redis缓存并以注解(@Cacheable、@CachePut、@CacheEvict)形式使用

maven项目中在pom.xml中依赖2个jar包,其他的spring的jar包省略:

<dependency>
  <groupId>redis.clients</groupId>
  <artifactId>jedis</artifactId>
  <version>2.8.1</version>
</dependency>
<dependency>
  <groupId>org.springframework.data</groupId>
  <artifactId>spring-data-redis</artifactId>
  <version>1.7.2.RELEASE</version>
</dependency> 

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:p="http://www.springframework.org/schema/p"
  xmlns:context="http://www.springframework.org/schema/context"
  xmlns:mvc="http://www.springframework.org/schema/mvc"
  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/mvc
            http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd
            http://www.springframework.org/schema/cache
            http://www.springframework.org/schema/cache/spring-cache-4.2.xsd">  

  <context:property-placeholder location="classpath:redis-config.properties" />  

  <!-- 启用缓存注解功能,这个是必须的,否则注解不会生效,另外,该注解一定要声明在spring主配置文件中才会生效 -->
  <cache:annotation-driven cache-manager="cacheManager" />  

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

   <bean id="JedisConnectionFactory" 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.RedisTemplate">
     <property name="connectionFactory" ref="JedisConnectionFactory" />
   </bean>  

   <!-- spring自己的缓存管理器,这里定义了缓存位置名称 ,即注解中的value -->
   <bean id="cacheManager" class="org.springframework.cache.support.SimpleCacheManager">
     <property name="caches">
      <set>
        <!-- 这里可以配置多个redis -->
        <!-- <bean class="com.cn.util.RedisCache">
           <property name="redisTemplate" ref="redisTemplate" />
           <property name="name" value="default"/>
        </bean> -->
        <bean class="com.cn.util.RedisCache">
           <property name="redisTemplate" ref="redisTemplate" />
           <property name="name" value="common"/>
           <!-- common名称要在类或方法的注解中使用 -->
        </bean>
      </set>
     </property>
   </bean>  

</beans>

redis-config.properties中的内容:

# Redis settings
# server IP
redis.host=127.0.0.1
# server port
redis.port=6379
# server pass
redis.pass=
# use dbIndex
redis.database=0
# 控制一个pool最多有多少个状态为idle(空闲的)的jedis实例
redis.maxIdle=300
# 表示当borrow(引入)一个jedis实例时,最大的等待时间,如果超过等待时间(毫秒),则直接抛出JedisConnectionException;
redis.maxWait=3000
# 在borrow一个jedis实例时,是否提前进行validate操作;如果为true,则得到的jedis实例均是可用的
redis.testOnBorrow=true

com.cn.util.RedisCache类中的内容:

package com.cn.util;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream; 

import org.springframework.cache.Cache;
import org.springframework.cache.support.SimpleValueWrapper;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate; 

public class RedisCache implements Cache{ 

  private RedisTemplate<String, Object> redisTemplate;
  private String name;
  public RedisTemplate<String, Object> getRedisTemplate() {
    return redisTemplate;
  } 

  public void setRedisTemplate(RedisTemplate<String, Object> redisTemplate) {
    this.redisTemplate = redisTemplate;
  } 

  public void setName(String name) {
    this.name = name;
  } 

  @Override
  public String getName() {
    // TODO Auto-generated method stub
    return this.name;
  } 

  @Override
  public Object getNativeCache() {
   // TODO Auto-generated method stub
    return this.redisTemplate;
  } 

  @Override
  public ValueWrapper get(Object key) {
   // TODO Auto-generated method stub
   System.out.println("get key");
   final String keyf = key.toString();
   Object object = null;
   object = redisTemplate.execute(new RedisCallback<Object>() {
   public Object doInRedis(RedisConnection connection)
         throws DataAccessException {
     byte[] key = keyf.getBytes();
     byte[] value = connection.get(key);
     if (value == null) {
       return null;
      }
     return toObject(value);
     }
    });
    return (object != null ? new SimpleValueWrapper(object) : null);
   } 

   @Override
   public void put(Object key, Object value) {
    // TODO Auto-generated method stub
    System.out.println("put key");
    final String keyf = key.toString();
    final Object valuef = value;
    final long liveTime = 86400;
    redisTemplate.execute(new RedisCallback<Long>() {
      public Long doInRedis(RedisConnection connection)
          throws DataAccessException {
        byte[] keyb = keyf.getBytes();
        byte[] valueb = toByteArray(valuef);
        connection.set(keyb, valueb);
        if (liveTime > 0) {
          connection.expire(keyb, liveTime);
         }
        return 1L;
       }
     });
   } 

   private byte[] toByteArray(Object obj) {
     byte[] bytes = null;
     ByteArrayOutputStream bos = new ByteArrayOutputStream();
     try {
      ObjectOutputStream oos = new ObjectOutputStream(bos);
      oos.writeObject(obj);
      oos.flush();
      bytes = bos.toByteArray();
      oos.close();
      bos.close();
     }catch (IOException ex) {
        ex.printStackTrace();
     }
     return bytes;
    }  

    private Object toObject(byte[] bytes) {
     Object obj = null;
      try {
        ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
        ObjectInputStream ois = new ObjectInputStream(bis);
        obj = ois.readObject();
        ois.close();
        bis.close();
      } catch (IOException ex) {
        ex.printStackTrace();
      } catch (ClassNotFoundException ex) {
        ex.printStackTrace();
      }
      return obj;
    } 

    @Override
    public void evict(Object key) {
     // TODO Auto-generated method stub
     System.out.println("del key");
     final String keyf = key.toString();
     redisTemplate.execute(new RedisCallback<Long>() {
     public Long doInRedis(RedisConnection connection)
          throws DataAccessException {
       return connection.del(keyf.getBytes());
      }
     });
    } 

    @Override
    public void clear() {
      // TODO Auto-generated method stub
      System.out.println("clear key");
      redisTemplate.execute(new RedisCallback<String>() {
        public String doInRedis(RedisConnection connection)
            throws DataAccessException {
         connection.flushDb();
          return "ok";
        }
      });
    } 

    @Override
    public <T> T get(Object key, Class<T> type) {
      // TODO Auto-generated method stub
      return null;
    } 

    @Override
    public ValueWrapper putIfAbsent(Object key, Object value) {
      // TODO Auto-generated method stub
      return null;
    } 

}

到了这一步,大部分人会想在web.xml的启动配置文件地方(context-param)加入了spring-redis.xml,让项目启动时加载这个配置文件吧,但是这样启动后注解不生效。

正确的做法是:web.xml中配置了servlet控制器:

<servlet>
 <servlet-name>SpringMVC</servlet-name>
 <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
 <init-param>
  <param-name>contextConfigLocation</param-name>
  <param-value>/WEB-INF/spring-mvc.xml</param-value>
 </init-param>
 <load-on-startup>1</load-on-startup>
 <async-supported>true</async-supported>
</servlet> 

在DispatcherServlet的初始化过程中,框架会在web应用的 WEB-INF文件夹下寻找名为spring-mvc.xml的配置文件,如果不指定的话,默认是applicationContext.xml

只需要在spring-mvc.xml文件中引入spring-redis配置文件即可,正如spring-redis.xml中的启用注解说的:<cache:annotation-driven cache-manager="cacheManager" />注解一定要声明在spring主配置文件中才会生效。

spring-mvc.xml内容,省略了spring与spring MVC整合的那部分:

<?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:mvc="http://www.springframework.org/schema/mvc"
  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/mvc
            http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd">
  <!-- 自动扫描该包,使SpringMVC认为包下用了@controller注解的类是控制器 -->
  <context:component-scan base-package="com.cn" />  

  <!-- 引入同文件夹下的redis属性配置文件 -->
  <import resource="spring-redis.xml"/> 

</beans>

在service的实现类中:

@Service
public class UserServiceImpl implements UserService{ 

  @Autowired
  private UserBo userBo; 

  @Cacheable(value="common",key="'id_'+#id")
  public User selectByPrimaryKey(Integer id) {
    return userBo.selectByPrimaryKey(id);
  } 

  @CachePut(value="common",key="#user.getUserName()")
  public void insertSelective(User user) {
    userBo.insertSelective(user);
  } 

  @CacheEvict(value="common",key="'id_'+#id")
  public void deleteByPrimaryKey(Integer id) {
    userBo.deleteByPrimaryKey(id);
  }
}

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

(0)

相关推荐

  • 详解Spring极速集成注解redis实录

    Redis 做为基于内存的 Key-Value 数据库,用来做缓存服务器性价比相当高. 官方推出的面向 Java 的 Client Jedis,提供了很多接口和方法,可以让 Java 操作使用 Redis. Spring Data Redis 为 Spring 团队对 Jedis 进行了封装,集成 Jedis 的一些命令和方法. 本文重点描述集成过程,能让你迅速的通过 spring-data-redis 将 redis 集成到 spring 项目中,毕竟大家都忙的. 1. 添加项目依赖 <!--

  • 配置Spring4.0注解Cache+Redis缓存的用法

    前言: 目前公司项目在上一个技术架构的处理,已经搭建好了Redis,但redis只用在了做session的管理,然而 后台的对象缓存没有用上 1. redis 和 ehcache的区别: 简单了解了下,个人觉得 从部署上而言,redis更适合分布式部署,ehcache是在每台应用服务器上开辟一块内存做缓存,集群时还得考虑缓存的情况, redis就不需要考虑缓存了.单独部署在一台服务器中(也可以是在某一台应用服务器中) 2. 项目配置(spring mvc+maven+mybaits+redis)

  • Spring Boot 基于注解的 Redis 缓存使用详解

    看文本之前,请先确定你看过上一篇文章<Spring Boot Redis 集成配置>并保证 Redis 集成后正常可用,因为本文是基于上文继续增加的代码. 一.创建 Caching 配置类 RedisKeys.Java package com.shanhy.example.redis; import java.util.HashMap; import java.util.Map; import javax.annotation.PostConstruct; import org.springf

  • 简单注解实现集群同步锁(spring+redis+注解)

    互联网面试的时候,是不是面试官常问一个问题如何保证集群环境下数据操作并发问题,常用的synchronized肯定是无法满足了,或许你可以借助for update对数据加锁.本文的最终解决方式你只要在方法上加一个@P4jSyn注解就能保证集群环境下同synchronized的效果,且锁的key可以任意指定.本注解还支持了锁的超时机制. 本文需要对Redis.spring和spring-data-redis有一定的了解.当然你可以借助本文的思路对通过注解对方法返回数据进行缓存,类似com.googl

  • Spring基于注解整合Redis完整实例

    在<Redis之--Spring整合Redis>一文中,向大家介绍了如何将spring与Redis整合起来,但不是基于注解的形式,很多同学都希望能够通过注解的形式来简单的将Spring与Redis整合起来,这样,在使用的时候,只需要在相应的方法上加上注解,便可以使方法轻松的调用Redis的缓存.那么今天就来向大家介绍如何用基于注解的形式来整合Spring与Redis. 一.项目搭建 今天,我们不使用hibernate来操作数据库了,我们今天选择的框架是: Spring4(包括mvc.conte

  • Spring与Mybatis基于注解整合Redis的方法

    基于这段时间折腾redis遇到了各种问题,想着整理一下.本文主要介绍基于Spring+Mybatis以注解的形式整合Redis.废话少说,进入正题. 首先准备Redis,我下的是Windows版,下载后直接启动redis-server就行了,见下图: 一,先上jar包 二,创建实体类 package com.sl.user.vo; import java.io.Serializable; import com.fasterxml.jackson.databind.PropertyNamingSt

  • spring整合redis缓存并以注解(@Cacheable、@CachePut、@CacheEvict)形式使用

    maven项目中在pom.xml中依赖2个jar包,其他的spring的jar包省略: <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>2.8.1</version> </dependency> <dependency> <groupId>org.springfra

  • 详解Spring缓存注解@Cacheable,@CachePut , @CacheEvict使用

    注释介绍 @Cacheable @Cacheable 的作用 主要针对方法配置,能够根据方法的请求参数对其结果进行缓存 @Cacheable 作用和配置方法 参数 解释 example value 缓存的名称,在 spring 配置文件中定义,必须指定至少一个 例如: @Cacheable(value="mycache") @Cacheable(value={"cache1","cache2"} key 缓存的 key,可以为空,如果指定要按照

  • spring整合redis实现数据缓存的实例代码

    数据缓存原因:有些数据比较多,如果每次访问都要进行查询,无疑给数据库带来太大的负担,将一些庞大的查询数据并且更新次数较少的数据存入redis,能为系统的性能带来良好的提升. 业务逻辑思路:登入系统,访问数据时,检查redis是否有缓存,有则直接从redis中提取,没有则从数据库查询出,并存入redis中做缓存. 为什么要用redis做缓存: (1)异常快速:Redis的速度非常快,每秒能执行约11万集合,每秒约81000+条记录. (2)支持丰富的数据类型:Redis支持最大多数开发人员已经知道

  • SpringBoot2.3整合redis缓存自定义序列化的实现

    1.引言 我们使用redis作为缓存中间件时,当我们第一次查询数据的时候,是去数据库查询,然后查到的数据封装到实体类中,实体类会被序列化存入缓存中,当第二次查数据时,会直接去缓存中查找被序列化的数据,然后反序列化被我们获取.我们在缓存中看到的序列化数据不直观,如果想看到类似json的数据格式,就需要自定义序列化规则. 2.整合redis pom.xml: <!--引入redis--> <dependency> <groupId>org.springframework.d

  • SpringBoot详解整合Redis缓存方法

    目录 1.Spring Boot支持的缓存组件 2.基于注解的Redis缓存实现 3.基于API的Redis缓存实现 1.Spring Boot支持的缓存组件 在Spring Boot中,数据的缓存管理存储依赖于Spring框架中cache相关的org.springframework.cache.Cache和org.springframework.cache.CacheManager缓存管理器接口. 如果程序中没有定义类型为CacheManager的Bean组件或者是名为cacheResolve

  • Spring整合redis(jedis)实现Session共享的过程

    今天来记录一下自己在整合框架过程中所遇到的问题: 1.    在用redis实现session共享时,项目启动报 No bean named 'springSessionRepositoryFilter' is defined 异常 2.    在调用缓存工具类的时候显示注入的JedisPool为Null (一个跟spring扫描有关的细节错误) 好了,开始上我整合的文件了 pom.xml依赖jar包 <!-- spring session begin --> <dependency&g

  • Spring Cache+Redis缓存数据的实现示例

    目录 1.为什么使用缓存 2.常用的缓存注解 2.1 @Cacheable 2.2 @CacheEvict 2.3.@Cacheput 2.4.@Caching 2.5.@CacheConfig 3.SpringBoot缓存支持 4.项目继承Spring Cache+Redis 4.1 添加依赖 4.2 配置类 4.3 添加redis配置 4.4 接口中使用缓存注解 4.5 缓存效果测试 1.为什么使用缓存   我们知道内存的读取速度远大于硬盘的读取速度.当需要重复地获取相同数据时,一次一次地请

  • spring整合redis消息监听通知使用的实现示例

    目录 问题引入 1.1 过期问题描述 1.2 常用解决方案分析 1.3.整合SpringData Redis开发 spring整合redis监听消息 1. 配置监听redis消息 2 测试消息 结合redis的key失效机制和消息完成过期优惠券处理 1 模拟过期代金卷案例 2 配置redis中key失效的消息监听 3 接收失效消息完成过期代金卷处理 问题引入 在电商系统中,秒杀,抢购,红包优惠卷等操作,一般都会设置时间限制,比如订单15分钟不付款自动关闭,红包有效期24小时等等.那对于这种需求最

  • SpringBoot详解如何整合Redis缓存验证码

    目录 1.简介 2.介绍 3.前期配置 3.1.坐标导入 3.2.配置文件 3.3.配置类 4.Java操作Redis 1.简介 Redis is an open source (BSD licensed), in-memory data structure store, used as a database, cache, and message broker. 翻译:Redis 是一个开源的内存中的数据结构存储系统,它可以用作:数据库.缓存和消息中间件. 官网链接:https://redis

  • Spring整合redis的操作代码

    目录 导入坐标 配置文件 进行操作 StringRedisTemplate jedis 导入坐标 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> 配置文件 spring: redis: host: localhost port: 6

随机推荐