Spring boot系列--redis使用之1

7 篇文章 1 订阅
4 篇文章 0 订阅

简介

在互联网的应用中,redis被广泛地使用。而在spring boot中使用redis,是非常简单的。

spring boot 中的redis

要在spring boot中使用redis,在pom中加入spring-boot-starter-redis依赖。maven会添加spring-data-redis包,其中包含了jedis,jredis,lettuce,srp几种实现。spring boot缺省选择jedis实现使用。

jedis配置

缺省使用localhost的redis配置,如果你没有修改任何配置,在本机上测试,不需要做任何配置。但在生成环境,必须配置真实的环境。

spring:
    # REDIS (RedisProperties)
    redis:
        # Redis数据库索引(默认为0)    
        database:0
        # Redis服务器地址
        host:localhost
        # Redis服务器连接端口
        port:6379
        # Redis服务器连接密码(默认为空)
        password:
        # 连接池最大连接数(使用负值表示没有限制)
        pool.max-active:8
        # 连接池最大阻塞等待时间(使用负值表示没有限制)
        pool.max-wait:-1
        # 连接池中的最大空闲连接
        pool.max-idle:8
        # 连接池中的最小空闲连接
        pool.min-idle:0
        # 连接超时时间(毫秒)
        timeout:0

使用StringRedisTemplate来处理String

在spring-data-redis中提供了StringRedisTemplate,可以直接用来处理String数据了。

// 可以直接使用,spring会绑定 
@Autowired
private StringRedisTemplate template;

@RequestMapping("/foo")
@ResponseBody
public String foo() {
        ValueOperations<String, String> ops = template.opsForValue();
        String key = "spring.boot.redis.test";
        if (!this.template.hasKey(key)) {
            String str = "not found the key, now set it";
            log.info(str);
            ops.set(key, str);
            return str;
        } else {

            String str = "Found key " + key + ", value=" + ops.get(key);
            log.info(str);
            return str;
        }

    }   

可以看一下spring中的实现类:

/*
 * Copyright 2011-2013 the original author or authors.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.springframework.data.redis.core;

import org.springframework.data.redis.connection.DefaultStringRedisConnection;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.StringRedisConnection;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

/**
 * String-focused extension of RedisTemplate. Since most operations against Redis are String based, this class provides
 * a dedicated class that minimizes configuration of its more generic {@link RedisTemplate template} especially in terms
 * of serializers.
 * <p/>
 * Note that this template exposes the {@link RedisConnection} used by the {@link RedisCallback} as a
 * {@link StringRedisConnection}.
 * 
 * @author Costin Leau
 */
public class StringRedisTemplate extends RedisTemplate<String, String> {

    /**
     * Constructs a new <code>StringRedisTemplate</code> instance. {@link #setConnectionFactory(RedisConnectionFactory)}
     * and {@link #afterPropertiesSet()} still need to be called.
     */
    public StringRedisTemplate() {
        RedisSerializer<String> stringSerializer = new StringRedisSerializer();
        setKeySerializer(stringSerializer);
        setValueSerializer(stringSerializer);
        setHashKeySerializer(stringSerializer);
        setHashValueSerializer(stringSerializer);
    }

    /**
     * Constructs a new <code>StringRedisTemplate</code> instance ready to be used.
     * 
     * @param connectionFactory connection factory for creating new connections
     */
    public StringRedisTemplate(RedisConnectionFactory connectionFactory) {
        this();
        setConnectionFactory(connectionFactory);
        afterPropertiesSet();
    }

    protected RedisConnection preProcessConnection(RedisConnection connection, boolean existingConnection) {
        return new DefaultStringRedisConnection(connection);
    }
}

在实现中,RedisTemplate和其子类中包含了几种不同的Serializer,分别对应Key,Value,Hash……,而最简单的String类型,在stringSerializer变量上实例化为StringRedisSerializer。

public class RedisTemplate<K, V> extends RedisAccessor implements RedisOperations<K, V>, BeanClassLoaderAware {

    private boolean enableTransactionSupport = false;
    private boolean exposeConnection = false;
    private boolean initialized = false;
    private boolean enableDefaultSerializer = true;
    private RedisSerializer<?> defaultSerializer;
    private ClassLoader classLoader;

    private RedisSerializer keySerializer = null;
    private RedisSerializer valueSerializer = null;
    private RedisSerializer hashKeySerializer = null;
    private RedisSerializer hashValueSerializer = null;
    private RedisSerializer<String> stringSerializer = new StringRedisSerializer();

 ...

 /**
   * Constructs a new <code>RedisTemplate</code> instance.
   */
    public RedisTemplate() {}

    public void afterPropertiesSet() {

        super.afterPropertiesSet();

        boolean defaultUsed = false;

        if (defaultSerializer == null) {

            defaultSerializer = new JdkSerializationRedisSerializer(
                    classLoader != null ? classLoader : this.getClass().getClassLoader());
        }

        if (enableDefaultSerializer) {

            if (keySerializer == null) {
                keySerializer = defaultSerializer;
                defaultUsed = true;
            }
            if (valueSerializer == null) {
                valueSerializer = defaultSerializer;
                defaultUsed = true;
            }
            if (hashKeySerializer == null) {
                hashKeySerializer = defaultSerializer;
                defaultUsed = true;
            }
            if (hashValueSerializer == null) {
                hashValueSerializer = defaultSerializer;
                defaultUsed = true;
            }
        }

        if (enableDefaultSerializer && defaultUsed) {
            Assert.notNull(defaultSerializer, "default serializer null and not all serializers initialized");
        }

        if (scriptExecutor == null) {
            this.scriptExecutor = new DefaultScriptExecutor<K>(this);
        }

        initialized = true;
    }

} 

可以看到spring boot应用在启动时,如果没有检查到对应的对象配置,则最后实例化defaultSerializer对象为JdkSerializationRedisSerializer了。

可以看一下运行时的对象
StringRedisTemplate对象实例

使用RedisTemplate

在程序中使用 RedisTemplate,如上所说,需要配置对应的serializer,否则对对应的数据处理时,要么serializer对象为null,要么使用的缺省的则使用JdkSerializationRedisSerializer。

要配置我们的redisTemplate对象,可以在配置类中定义一个redisTemplate 的bean。

@Bean  
    public RedisTemplate<String, ? extends Object> redisTemplate(  
            RedisConnectionFactory factory) {  
        StringRedisTemplate template = new StringRedisTemplate(factory);  
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);  
        ObjectMapper om = new ObjectMapper();  
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);  
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);  
        jackson2JsonRedisSerializer.setObjectMapper(om);  
        template.setValueSerializer(jackson2JsonRedisSerializer);  
        template.afterPropertiesSet();  
        return template;  
    } 

在配置类中,定义了Jackson2JsonRedisSerializer,来作为ValueSerializer对象,对Model对象进行序列化和反序列化。

然后在程序处理的地方,可以使用这个bean对象了。

@Autowired
private RedisTemplate redisTemplate;


@RequestMapping("/user/{id}")
@ResponseBody
public String getUser(@PathVariable("id") long id) {
    log.info("---- getUser");
    //
    User user = new User(id, "aa@126.com", "aa", "aa123456", "aa", "123");
    ValueOperations<String, User> operations = redisTemplate.opsForValue();
    operations.set("com.dcloud.user", user);
    // 有超时时间的redis set..
    operations.set("com.dcloud.user.ex", user, 10, TimeUnit.SECONDS);

    //
    boolean exists = redisTemplate.hasKey("com.dcloud.user");
    if (exists) {
        log.info("exists is true");
    } else {
        log.info("exists is false");
    }

    return "finished";
}


@RequestMapping(value = "/query")
@ResponseBody
public String query() {
    log.info("query from redis");
    ValueOperations<String, User> operations = redisTemplate.opsForValue();
    // 
    User ret = operations.get("com.dcloud.user");
    if (null == ret) {
        log.info("not exist user");
        return "finished query, and not exists";
    }

    log.info(ret.toString());

    return "finished query";
}

现在可以看一下运行时的redisTemplate对象
配置的redisTemple

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值