整合方式


使用Jedis

Jedis是Redis官方推薦的面向Java的操作Redis的客戶端,是對服務端直連後進行操作。如果直接使用Jedis進行連線,多執行緒環境下是非執行緒安全的,正式生產環境一般使用連線池進行連線。

<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
</dependency>
使用spring-data-redis

由Spring 框架提供,是對Redis客戶端的進一步封裝,遮蔽了不同客戶端的不同實現方式,讓服務端和客戶端進一步解耦;也就是你可以切換不同的客戶端實現,比如Jedis或Lettuce(Redis客戶端實現之一),而不影響你的業務邏輯。

類似於的SpringCloud的服務治理框架對不同服務治理元件的適配,或是AMQP

它利用RedisTemplate對JedisApi進行高度封裝。使用的依賴如下:

 <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

Redis的安裝


​ 收先要安裝Redis服務端,Redis官方提供的是Linux安裝包。網上有很多詳細的安裝教程,這裡不做展開。關於Windows下的安裝,可參考我的另一篇博文windows下Redis的安裝和使用

繫結配置


​ 完成Redis服務端的安裝之後,我們開始在專案中進行整合。這裡我們先介紹使用Jedis的方式進行的整合。先按上面的提及的方式進行依賴的引入。然後將Redis的相關資訊配置到配置檔案中去。我們可以的新建一個配置檔案redis.properties,內容如下:

# Redis資料庫索引(預設為0)
spring.redis.database=0
# Redis伺服器地址
spring.redis.host=127.0.0.1
# Redis伺服器連線埠
spring.redis.port=6379
# Redis伺服器連線密碼(預設為空)
spring.redis.password=
# 連線超時時間(毫秒)
spring.redis.timeout=0

​ 接下來我們要為Redis客戶端連線繫結上面的配置,創建出來的客戶端例項才能夠連線到我們的想連的Redis服務端。你可以使用@Value註解或@ConfigurationProperties註解的方式,本文采用的是後者,如果還不清楚的該註解的用法,可以移步我的另一篇博文@ConfigurationProperties實現自定義配置繫結檢視,這裡不做展開。

​ 以下是Redis服務端資訊配置的接收類:MyRedisProperties.java

@ConfigurationProperties(
prefix = "spring.redis"
)
@Component
@Data
@PropertySource("classpath:/redis.properties")
public class MyRedisProperties {
private String database;
private String host;
private Integer port;
private String password;
private Integer timeOut;
}

由於我們正式生產環境一般都是採用連線池方式實現,所以我們還需要關於連線池的配置如下:

# 連線池最大連線數(使用負值表示沒有限制)
spring.redis.pool.max-active=8
# 連線池最大阻塞等待時間(使用負值表示沒有限制)
spring.redis.pool.max-wait=-1
# 連線池中的最大空閒連線
spring.redis.pool.max-idle=8
# 連線池中的最小空閒連線
spring.redis.pool.min-idle=0

對應的接收類如下:

@ConfigurationProperties(
prefix = "spring.redis.pool"
)
@Data
@Component
@PropertySource("classpath:/redis.properties")
public class RedisPoolProperties { private Integer maxActive;
private Integer maxWait;
private Integer maxIdle;
private Integer minIdle;
}

然後向Spring容器裝配客戶端例項,分為單個客戶端和連線池兩種實現,如下程式碼:

@Configuration
public class RedisConfig { @Autowired
private RedisPoolProperties redisPoolProperties;
@Autowired
private MyRedisProperties myRedisProperties; @Bean
public Jedis singleJedis(){
return new Jedis(myRedisProperties.getHost(),myRedisProperties.getPort());
} @Bean
public JedisPool jedisPool(){
JedisPoolConfig poolConfig = new JedisPoolConfig();
poolConfig.setMaxIdle(redisPoolProperties.getMaxIdle());
poolConfig.setMaxTotal(redisPoolProperties.getMaxActive());
poolConfig.setMaxWaitMillis(redisPoolProperties.getMaxWait() * 1000);
JedisPool jp = new JedisPool(poolConfig, myRedisProperties.getHost(), myRedisProperties.getPort(),
myRedisProperties.getTimeOut()*1000, myRedisProperties.getPassword(), 0);
return jp; }
}

獲取Redis客戶端


進行相關配置的繫結之後,意味著我們程式可以拿到Redis和連線池的相關資訊,然後進行客戶端的建立和連線了。所以我們要向Spring容器裝配客戶端例項,分為單個客戶端和連線池兩種實現,如下程式碼:

@Configuration
public class RedisConfig { @Autowired
private RedisPoolProperties redisPoolProperties;
@Autowired
private MyRedisProperties myRedisProperties; @Bean
public Jedis singleJedis(){
return new Jedis(myRedisProperties.getHost(),myRedisProperties.getPort());
} @Bean
public JedisPool jedisPool(){
JedisPoolConfig poolConfig = new JedisPoolConfig();
poolConfig.setMaxIdle(redisPoolProperties.getMaxIdle());
poolConfig.setMaxTotal(redisPoolProperties.getMaxActive());
poolConfig.setMaxWaitMillis(redisPoolProperties.getMaxWait() * 1000);
JedisPool jp = new JedisPool(poolConfig, myRedisProperties.getHost(), myRedisProperties.getPort(),
myRedisProperties.getTimeOut()*1000, myRedisProperties.getPassword(), 0);
return jp; }
}

Redis工具的編寫


裝配好客戶端例項後,我們就可以通過@Autowired的方式進行注入使用了。我們都知道,Redis有5中資料型別,分別是:

  • string(字串)
  • hash(雜湊)
  • list(列表)
  • set(集合)
  • zset(sorted set:有序集合)

所以的有必要的封裝一個操作者5種資料列表的工具類,由於篇幅的關係,我們以Redis最基本的資料型別String為例,簡單封裝幾個操作方法作為示例如下,更詳細的封裝,可參考java操作Redis資料庫的redis工具,RedisUtil,jedis工具JedisUtil,JedisPoolUtil這一博文

@Service
public class RedisService { @Autowired
private JedisPool jedisPool; // 連線池方式
@Autowired
private Jedis myJedis; // 單個客戶端 public <T> T get(String key, Class<T> clazz) {
Jedis jedis = null;
try {
jedis = jedisPool.getResource();
String str = jedis.get(key);
return stringToBean(str,clazz);
} finally {
close(jedis);
}
} public <T> void set(String key, T value) {
try {
String str = value.toString();
if (str == null || str.length() <= 0) {
return;
}
myJedis.set(key, str);
} finally {
close(myJedis);
}
} private void close(Jedis jedis) {
if (jedis != null) {
jedis.close();
}
} /**
* 把一個字串轉換成bean物件
* @param str
* @param <T>
* @return
*/
public static <T> T stringToBean(String str, Class<T> clazz) { if(str == null || str.length() <= 0 || clazz == null) {
return null;
} if(clazz == int.class || clazz == Integer.class) {
return (T)Integer.valueOf(str);
}else if(clazz == String.class) {
return (T)str;
}else if(clazz == long.class || clazz == Long.class) {
return (T)Long.valueOf(str);
}else {
return JSON.toJavaObject(JSON.parseObject(str), clazz);
}
}
}

其中get方法使用連線池中的客戶端例項,set方法用到的是非連線池的例項,以區分兩種不同的使用方式

使用


封裝好的Redis的操作工具類後,我們就可以直接使用該工具類來進行對Redis的各種操作 。如下,直接注入即可。

@RestController
public class TestController { @Autowired
private RedisService redisService; ......
}