1. 程式人生 > >Redis之整合SpringBoot

Redis之整合SpringBoot

Jedis是Redis官方推薦的面向Java的操作Redis的客戶端,而RedisTemplate是SpringDataRedis中對JedisApi的高度封裝。

一、Jedis

①pom.xml

<dependency>
	<groupId>redis.clients</groupId>
	<artifactId>jedis</artifactId>
</dependency>

②applicaton.properties

#redis伺服器地址
jedis.pool.host=192.168.124.128
#redis伺服器埠
jedis.pool.port=6379
#redis的auth密碼
jedis.pool.password=123456
#連線池最大連線數(使用負值表示沒有限制)
jedis.pool.config.maxTotal=60
# 連線池最大阻塞等待時間(使用負值表示沒有限制)
jedis.pool.config.maxWait=100
#最大空閒連線
jedis.pool.config.maxIdle=50
#最小空閒連線
jedis.pool.config.minIdle=0

③JedisConfig

package com.yj.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.Protocol;

@Configuration
public class JedisConfig {

	@Bean(name = "jedis.pool")
	@Autowired
	public JedisPool jedisPool(@Qualifier("jedis.pool.config") JedisPoolConfig config,
			@Value("${jedis.pool.host}") String host, @Value("${jedis.pool.port}") int port,
			@Value("${jedis.pool.password}") String password) {
		return new JedisPool(config, host, port, Protocol.DEFAULT_TIMEOUT, password);
	}

	@Bean(name = "jedis.pool.config")
	public JedisPoolConfig jedisPoolConfig(@Value("${jedis.pool.config.maxTotal}") int maxTotal,
			@Value("${jedis.pool.config.maxWait}") int maxWait,
			@Value("${jedis.pool.config.maxIdle}") int maxIdle,@Value("${jedis.pool.config.minIdle}") int minIdle) {
		JedisPoolConfig config = new JedisPoolConfig();
		config.setMaxTotal(maxTotal);
		config.setMaxWaitMillis(maxWait);
		config.setMaxIdle(maxIdle);
		config.setMinIdle(minIdle);
		return config;
	}
}

二、JedisCluster

①pom.xml

<dependency>
	<groupId>redis.clients</groupId>
	<artifactId>jedis</artifactId>
</dependency>

②application.properties

# Redis伺服器地址
spring.redis.cluster.nodes=192.168.124.128:7000,192.168.124.128:7001,192.168.124.128:7002,192.168.124.128:7006,192.168.124.129:7003,192.168.124.129:7004,192.168.124.129:7005,192.168.124.129:7007
# Redis伺服器密碼
spring.redis.cluster.password=123456
# 連線池最大連線數(使用負值表示沒有限制)
spring.redis.pool.max-active=60
# 連線池最大阻塞等待時間(使用負值表示沒有限制)
spring.redis.pool.max-wait=100
# 連線池中的最大空閒連線
spring.redis.pool.max-idle=50
# 連線池中的最小空閒連線
spring.redis.pool.min-idle=0
# 連線超時時間(毫秒)
spring.redis.timeout=200

③JedisClusterConfig

package com.yj.config;

import java.util.HashSet;
import java.util.Set;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.StringUtils;
import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.JedisCluster;
import redis.clients.jedis.JedisPoolConfig;

@Configuration
public class JedisClusterConfig {

    @Value("${spring.redis.cluster.nodes}")
    private String clusterNodes;
    @Value("${spring.redis.cluster.password:}")
    private String password;
    @Value("${spring.redis.timeout}")
    private int timeout;
    @Value("${spring.redis.pool.max-idle}")
    private int maxIdle;
    @Value("${spring.redis.pool.max-active}")
    private int maxActive;
    @Value("${spring.redis.pool.max-wait}")
    private long maxWaitMillis;
    @Value("${spring.redis.commandTimeout:5000}")
    private int commandTimeout;
    @Value("${spring.redis.socketTimeout:1000}")
    private int socketTimeout;
    @Value("${spring.redis.maxAttempts:1000}")
    private int maxAttempts;

    @Bean
    public JedisCluster getJedisCluster() {
        String[] cNodes = clusterNodes.split(",");
        Set<HostAndPort> nodes =  new HashSet<HostAndPort>();
        for(String node : cNodes) {
            String[] hp = node.split(":");
            nodes.add(new HostAndPort(hp[0],Integer.parseInt(hp[1])));
        }
        JedisPoolConfig jedisPoolConfig =new JedisPoolConfig();
        jedisPoolConfig.setMaxIdle(maxIdle);
        jedisPoolConfig.setMaxWaitMillis(maxWaitMillis);
        jedisPoolConfig.setMaxTotal(maxActive);
        if (StringUtils.isEmpty(password)) {
            return new JedisCluster(nodes, commandTimeout, jedisPoolConfig);
        }
        return new JedisCluster(nodes, commandTimeout, socketTimeout, maxAttempts, password, jedisPoolConfig);
    }
}

三、RedisTemple

分為RedisTemple和StringRedisTemple

①pom.xml

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-redis</artifactId>
	<version>1.3.2.RELEASE</version>
</dependency>
<dependency>
	<groupId>com.alibaba</groupId>
	<artifactId>fastjson</artifactId>
	<version>1.2.16</version>
</dependency>

②application.properties

# Redis伺服器地址
spring.redis.hostName=192.168.124.128
# Redis伺服器連線埠
spring.redis.port=6379
# Redis伺服器連線密碼
spring.redis.password=123456
# Redis資料庫索引(預設為0)
spring.redis.database=0
# 連線池最大連線數(使用負值表示沒有限制)
spring.redis.pool.max-active=60
# 連線池最大阻塞等待時間(使用負值表示沒有限制)
spring.redis.pool.max-wait=100
# 連線池中的最大空閒連線
spring.redis.pool.max-idle=50
# 連線池中的最小空閒連線
spring.redis.pool.min-idle=0
# 連線超時時間(毫秒)
spring.redis.timeout=200

③RedisTemplateConfig

package com.yj.config;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import redis.clients.jedis.JedisPoolConfig;

@Configuration
public class RedisTemplateConfig {

	private Logger logger = LoggerFactory.getLogger(RedisTemplateConfig.class);
	
	@Bean
	@ConfigurationProperties(prefix="spring.redis")
	public JedisPoolConfig getRedisConfig(){
		JedisPoolConfig config = new JedisPoolConfig();
		return config;
	}
	
	@Bean
	@ConfigurationProperties(prefix="spring.redis")
	public JedisConnectionFactory getConnectionFactory(){
		JedisConnectionFactory factory = new JedisConnectionFactory();
		JedisPoolConfig config = getRedisConfig();
		factory.setPoolConfig(config);
		logger.info("JedisConnectionFactory bean init success");
		return factory;
	}

	@Bean
	public RedisTemplate redisTemplate(RedisConnectionFactory connectionFactory) {
		RedisTemplate<Object, Object> template = new RedisTemplate<>();
		template.setConnectionFactory(connectionFactory);

		// 使用Jackson2JsonRedisSerializer來序列化和反序列化redis的value值(預設使用JDK的序列化方式)
		Jackson2JsonRedisSerializer serializer = new Jackson2JsonRedisSerializer(Object.class);

		ObjectMapper mapper = new ObjectMapper();
		mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
		mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
		serializer.setObjectMapper(mapper);

		template.setValueSerializer(serializer);
		// 使用StringRedisSerializer來序列化和反序列化redis的key值
		template.setKeySerializer(new StringRedisSerializer());
		template.afterPropertiesSet();
		return template;
	}

	@Bean
	public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory factory) {
		StringRedisTemplate stringRedisTemplate = new StringRedisTemplate();
		stringRedisTemplate.setConnectionFactory(factory);
		return stringRedisTemplate;
	}
}

使用

package com.yj;

import java.util.Date;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.yj.entity.User;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisCluster;
import redis.clients.jedis.JedisPool;

public class RedisClientTest extends ApplicationTest {

	private Logger logger = LoggerFactory.getLogger(ClientTest.class);

	@Autowired
	private JedisPool jedisPool;

	@Autowired
	private JedisCluster jedisCluster;

	@Autowired
	private RedisTemplate<String, Object> redisTemplate;

	@Autowired
	private RedisTemplate<String, String> stringRedisTemplate;

	@Test
	public void testJedis() {
		Jedis jedis = jedisPool.getResource();
		jedis.set("Jedis", JSON.toJSONString(getUser()));
		String userStr = jedis.get("Jedis");
		User value = JSONObject.parseObject(userStr, User.class);
		logger.info("Jedis:" + value);
	}

	@Test
	public void testJedisCluster() {
		jedisCluster.set("JedisCluster", JSON.toJSONString(getUser()));
		String userStr = jedisCluster.get("JedisCluster");
		User value = JSONObject.parseObject(userStr, User.class);
		logger.info("JedisCluster:" + value);
	}

	@Test /* 模板Bean已經配置了序列化和反序列化的策略 */
	public void testRedisTemplate() {
		redisTemplate.opsForValue().set("redisTemplate", getUser());
		User value = (User) redisTemplate.opsForValue().get("redisTemplate");
		logger.info("RedisTemplate:" + value);
	}

	@Test
	public void testStringRedisTemplate() {
		stringRedisTemplate.opsForValue().set("StringRedisTemplate", JSON.toJSONString(getUser()));
		String value = stringRedisTemplate.opsForValue().get("StringRedisTemplate");
		logger.info("StringRedisTemplate:" + value);
	}

	private User getUser() {
		User user = new User();
		user.setName("yj");
		user.setAge(18);
		user.setDate(new Date());
		return user;
	}
}