1.为什么使用Redis来做缓存呢?
Redis是内存数据库,把数据存到内存中,那么读写就变得非常快。
2.一个项目中有多个系统,我们要在哪个系统集成
在后台系统中添加,在接口的提供方添加缓存。
Redis与spring的集成
1.添加jedis依赖
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.6.0</version>
</dependency>
2.创建redis.properties外部配置文件
redis.maxTotal=100
redis.node1.ip=127.0.0.1
redis.node1.port=6379
3.spring容器读取该配置文件,并与redis进行整合
<!-- 读取资源文件 -->
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<!-- 允许JVM参数覆盖 -->
<property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" />
<!-- 忽略没有找到的资源文件 -->
<property name="ignoreResourceNotFound" value="true" />
<!-- 配置资源文件 -->
<property name="locations">
<list>
<value>classpath:redis.properties</value>
</list>
</property>
</bean>
Jedis的三种使用方法:1)普通使用2)连接池3)分片式集群。
现在我们选用分片式集群,那么该集群中的配置都需要与Spring进行整合
<!-- 定义连接池配置 -->
<bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
<!--最大连接数 -->
<property name="maxTotal" value="${redis.maxTotal}"/>
</bean>
<!-- 定义分片式连接池 -->
<bean class="redis.clients.jedis.ShardedJedisPool" destroy-method="close">
<constructor-arg index="0" ref="jedisPoolConfig"/>
<constructor-arg index="1">
<list>
<!--配置集群的节点信息 -->
<bean class="redis.clients.jedis.JedisShardInfo">
<constructor-arg index="0" value="${redis.node1.ip}"/>
<constructor-arg index="1" value="${redis.node1.port}"/>
</bean>
<!-- <bean class="redis.clients.jedis.JedisShardInfo">
<constructor-arg index="0" value="${redis.node2.ip}"/>
<constructor-arg index="1" value="${redis.node2.port}"/>
</bean> -->
</list>
</constructor-arg>
</bean>
4.封装RedisService(自己要会写)
写一个通用的service让Jedis和Redis进行交互。在其他service中只需要注入该service就可以。对Jedis中的集群方法进行的改造如下:
package com.taotao.manager.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class RedisService {
@Autowired
private ShardeJedisPool shardeJedisPool;
public String set(String key,String value){
ShardeJedis shardeJedis=null;
try {
// 从连接池中获取到jedis分片对象
shardeJedis=shardeJedisPool.getResource();
return shardeJedis.set(key,value);
} catch (Exception e) {
e.printStackTrace();
}finally{
if(null!=shardeJedis){
// 关闭,检测连接是否有效,有效就放回到连接池中,无效就重置状态
shardeJedis.close();
}
}
return null;
}
public String get(String key){
ShardeJedis shardeJedis=null;
try {
// 从连接池中获取到jedis分片对象
shardeJedis=shardeJedisPool.getResource();
return shardeJedis.get(key);
} catch (Exception e) {
e.printStackTrace();
}finally{
if(null!=shardeJedis){
// 关闭,检测连接是否有效,有效就放回到连接池中,无效就重置状态
shardeJedis.close();
}
}
return null;
}
}
以上代码存在的问题:代码的重用性差,只有一个语句不同。需要对代码进行抽取。
1.在service中创建一个Function的接口
2.编写接口代码
package com.taotao.manager.service;
import javax.security.auth.callback.Callback;
public interface Function<E,T> {
public T callback(E e);
}
service代码改造如下:
package com.taotao.manager.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import redis.clients.jedis.ShardedJedis;
import redis.clients.jedis.ShardedJedisPool;
@Service
public class RedisService {
@Autowired
private ShardedJedisPool shardedJedisPool;
private <T>T execute(Function<ShardedJedis, T> function){
ShardedJedis shardedJedis=null;
try {
shardedJedis=shardedJedisPool.getResource();
return function.callback(shardedJedis);
} catch (Exception e) {
e.printStackTrace();
}finally{
if (null!=shardedJedis) {
shardedJedis.close();
}
}
return null;
}
/**
* 设置值
* @param key
* @param value
* @return
*/
public String set(final String key,final String value){
return this.execute(new Function<ShardedJedis, String>() {
public String callback(ShardedJedis shardedJedis) {
return shardedJedis.set(key, value);
}
});
}
/**
* 获取值
* @param key
* @return
*/
public String get(final String key){
return this.execute(new Function<ShardedJedis, String>() {
public String callback(ShardedJedis shardedJedis) {
return shardedJedis.get(key);
}
});
}
/**
* 删除值
* @param key
* @return
*/
public Long del(final String key){
return this.execute(new Function<ShardedJedis, Long>() {
public Long callback(ShardedJedis shardedJedis) {
return shardedJedis.del(key);
}
});
}
/**
* 设置生存时间
*
* @param key
* @return
*/
public Long expire(final String key, final Integer seconds) {
return this.execute(new Function<ShardedJedis, Long>() {
@Override
public Long callback(ShardedJedis e) {
return e.expire(key, seconds);
}
});
}
/**
* 设置值以及生存时间,单位为秒
*
* @param key
* @param value
* @param seconds
* @return
*/
public String set(final String key, final String value, final Integer seconds) {
return this.execute(new Function<ShardedJedis, String>() {
@Override
public String callback(ShardedJedis jedis) {
String result = jedis.set(key, value);
jedis.expire(key, seconds);
return result;
}
});
}
}
上面的代码自己理解还是有些不容易。