3.2Redis和Spring整合应用

redis在日常工作容易用的很紧密,势必要和spring进行整合,spring框架提供了RedisTemplate,这是一个非常好的组件,采用Template的设计模式。

Template在spring框架中用的非常非常多,后面的mq组件、mongodb组件都要用到这些template。

下面讲一下整合,还是比较容易的。

添加依赖

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

<!-- spring相关忽略 -->

这两个是spring整合需要额外新增的依赖, 一个是spring-data-redis,一个是jedis客户端,其余都是spring相关的,暂忽略

添加配置application.properties

redis.host=127.0.0.1
redis.port=6379
redis.pass=
redis.maxIdle=300
redis.testOnBorrow=true

这个和上一节讲的一致,默认只需要host和port两个就够了。

applicationContext-redis.xml 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:redis="http://www.springframework.org/schema/redis"
       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
                            http://www.springframework.org/schema/redis http://www.springframework.org/schema/redis/spring-redis.xsd">
    <description>spring-data-redis配置</description>

    <context:property-placeholder
            ignore-unresolvable="true" location="classpath:/application.properties"/>
    <context:annotation-config/>
    <context:component-scan base-package="com.critc"/><!--spring从该包下面自动扫描组件 -->
    <bean id="redisConnectionFactory"
         class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
        <property name="hostName" value="${redis.host}"></property>
        <property name="port" value="${redis.port}"></property>
        <property name="usePool" value="true"></property>
    </bean>

    <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
        <property name="connectionFactory" ref="redisConnectionFactory"></property>
    </bean>

    <bean id="stringRedisTemplate" class="org.springframework.data.redis.core.StringRedisTemplate">
        <property name="connectionFactory" ref="redisConnectionFactory"></property>
    </bean>
</beans>

redisConnectionFactory这一节是建立redis的连接词,这里面还有其他参数,比如最大连接数,空闲时间等等,如果需要进行redis连接调优时,需要调整这些参数。

RedisTemplateStringRedisTemplate是两个bean,其中第二个继承第一个。
RedisTemplate里面value的可以是string,也可以是其他对象,StringRedisTemplatevalue只能是string,这是因为好多redis应用都是简单的存字符串,如果是对象,还需要进行对象的序列化和反序列化操作。
举例如下:

序列化工具类SerializeUtil

public class SerializeUtil {
    public static byte[] serialize(Object object) {
        ObjectOutputStream oos = null;
        ByteArrayOutputStream baos = null;
        try {
            // 序列化
            baos = new ByteArrayOutputStream();
            oos = new ObjectOutputStream(baos);
            oos.writeObject(object);
            byte[] bytes = baos.toByteArray();
            return bytes;
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage(), e);
        }
    }

    public static Object deserialize(byte[] bytes) {
        ByteArrayInputStream bais = null;
        try {
            // 反序列化
            bais = new ByteArrayInputStream(bytes);
            ObjectInputStream ois = new ObjectInputStream(bais);
            return ois.readObject();
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage(), e);
        }
    }
}

序列化的工具类很多很多,这是自己写的一个,原理都一样,把这个类以流的方式读取为二级制,然后存在内存里。

RedisUtil工具类

@Component
public class RedisUtil {
   @Autowired
   private RedisTemplate<Serializable, Serializable> redisTemplate;

   /**
    * 设置key和对象的value
    * @param key
    * @param value
    */
   public void set(final String key, Object value) {
       final byte[] vbytes = SerializeUtil.serialize(value);
       redisTemplate.execute(new RedisCallback<Object>() {
           @Override
           public Object doInRedis(RedisConnection connection) throws DataAccessException {
               connection.set(redisTemplate.getStringSerializer().serialize(key), vbytes);
               return null;
           }
       });
   }

   /**
    * 设置key和value,并加上时间(秒)
    * @param key
    * @param value
    * @param l
    */
   public void set(final String key, Object value, final long l) {
       final byte[] vbytes = SerializeUtil.serialize(value);
       redisTemplate.execute(new RedisCallback<Object>() {
           @Override
           public Object doInRedis(RedisConnection connection) throws DataAccessException {
               connection.setEx(redisTemplate.getStringSerializer().serialize(key), l, vbytes);
               return null;
           }
       });
   }

   /**
    * 根据key来取值
    * @param key
    * @param elementType
    * @param <T>
    * @return
    */
   public <T> T get(final String key, Class<T> elementType) {
       return redisTemplate.execute(new RedisCallback<T>() {
           @Override
           public T doInRedis(RedisConnection connection) throws DataAccessException {
               byte[] keybytes = redisTemplate.getStringSerializer().serialize(key);
               if (connection.exists(keybytes)) {
                   byte[] valuebytes = connection.get(keybytes);
                   T value = (T) SerializeUtil.deserialize(valuebytes);
                   return value;
               }
               return null;
           }
       });
   }

   /**
    * 根据key删除该值
    * @param key
    */
   public void del(final String key) {
       final byte[] keyBytes = redisTemplate.getStringSerializer().serialize(key);
       redisTemplate.execute(new RedisCallback<Object>() {
           @Override
           public Object doInRedis(RedisConnection connection) throws DataAccessException {
               connection.del(keyBytes);
               return null;
           }
       });
   }
}

这是一个可以直接用的redis工具类,里面包含了设值、取值、根据key删除的方法。

测试使用

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath*:applicationContext-redis.xml"})
public class TestRedis {
    @Autowired
    private RedisUtil redisUtil;

    @Test
    public void testRedis() {
        redisUtil.set("name", "hello redis");//设置值
        System.out.println(redisUtil.get("name", String.class));//根据key取值
        redisUtil.del("name");//删除值
    }
}

这里面利用junit加载spring的配置文件,注入RedisUtil,进行一个测试

StringRedisTemplate使用

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath*:applicationContext-redis.xml"})
public class TestStringRedisTemplate {
    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Test
    public void testRedis() {
        stringRedisTemplate.opsForValue().set("name", "hello stringRedisTemplate");//设值
        System.out.println(stringRedisTemplate.opsForValue().get("name"));//取值
        stringRedisTemplate.delete("name");//删除
    }
}

StringRedisTemplate的使用非常简单,通过opsForValue()这个方法来获取ValueOperations并进行设值取值等的操作。

源码下载

[本工程详细源码]
(https://github.com/chykong/java_component/tree/master/chapter3_2_redis_spring)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,923评论 18 139
  • Spring Boot 参考指南 介绍 转载自:https://www.gitbook.com/book/qbgb...
    毛宇鹏阅读 46,953评论 6 342
  • application的配置属性。 这些属性是否生效取决于对应的组件是否声明为Spring应用程序上下文里的Bea...
    新签名阅读 5,426评论 1 27
  • 这些属性是否生效取决于对应的组件是否声明为 Spring 应用程序上下文里的 Bean(基本是自动配置的),为一个...
    发光的鱼阅读 1,446评论 0 14
  • 22天的行动营即将画上一个句号,行动营就如同大母鸡抚育着很多小鸡。在这22天的吸收中,我这只蛋的蛋壳裂了,一只全新...
    K少628阅读 323评论 0 5