公司突然需要集成redis做缓存,于是抽空看了下,感觉很简单,网络上也有很多案例,但是有的代码不够具体,有的jar包不够完整,虽然最后我也搞出来了,但是浪费了很多时间,现在有空就整理下自己的思路。
第一步,我们需要安装redis
windows版下载地址:https://github.com/ServiceStack/redis-windows(尽量安装最新版本)
第二步,下载jedis相关jar
java包下载地址:http://repo1.maven.org/maven2/redis/clients/jedis/2.8.1/jedis-2.8.1.jar(2.8.1是当时我下载的版本,可以删除后面路径下载自己需要的)
第三步,下载spring相关jar
这个我们项目原来自带的spring3.0,我就没有去下载最新的,需要的可以在网络上搜索下。
这三步是准备工作,做完之后才能开始进行spring和redis的整合。
我的jar:
jedis-2.3.1.jar
commons-pool2-2.2.jar
com.springsource.org.aopalliance-1.0.0.jar(这个spring的jar是不能缺少的)
spring-data-redis-1.3.4.RELEASE.jar
以及一些spring和springmvc的jar
这些jar我都已经上传到csdn了,需要的朋友可以在该网站下载(http://download.youkuaiyun.com/detail/klsstt/9476208)。
准备好jar包之后,开始整合工作:
第一步:
安装好windows版本redis服务器之后,启动服务器进行测试工作,测试服务器安装正常之后,可以创建一个properties文件,把服务器配置的信息填进去
#ip
redis.host=127.0.0.1
#端口
redis.port=6379
redis.default.db=0
redis.timeout=100000
redis.maxActive=300
redis.maxIdle=100
redis.maxWait=1000
redis.testOnBorrow=true
如果你的项目已经有了一个properties文件,再引入多个properties文件时,
ignore-unresolvable="true" 这个属性一定要加上
- <context:property-placeholder location="classpath*:redis.properties" ignore-unresolvable="true" />
- <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
- <property name="locations">
- <list>
- <value>classpath*:mongodb.properties</value>
- </list>
- </property>
- <property name="ignoreUnresolvablePlaceholders" value="true" />
- </bean>
- <bean id="jedisConnectionFactory"
- class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"
- p:host-name="${redis.host}" p:port="${redis.port}" p:password="${redis.pass}"
- p:use-pool="true" />
<bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
<constructor-arg index="0">
<bean class="org.springframework.data.redis.connection.RedisSentinelConfiguration">
<property name="master">
<bean class="org.springframework.data.redis.connection.RedisNode" p:name="${redis.master.name}" c:host="${redis.master.host}" c:port="${redis.master.port}" />
</property>
<property name="sentinels">
<set>
<bean class="org.springframework.data.redis.connection.RedisNode" c:host="${redis.sentinels.n1.host}" c:port="${redis.sentinels.n1.port}" />
</set>
</property>
</bean>
</constructor-arg>
<constructor-arg index="1">
<ref bean="jedisPoolConfig" />
</constructor-arg>
<property name="timeout">
<value>${redis.timeout}</value>
</property>
</bean>
配置好连接池之后,引入RedisTemplate,就可以对redis进行操作了:
使用JdkSerializationRedisSerializer类,进行对象和byte[]之间的相互转换,就像之前已经做得那样。
通常情况下,我们使用字符串形式的key即可,因此:指定keySerializer为StringRedisSerializer类
使用redisTemplate:作为字段,注入到Service层即可。
<bean id="stringRedisSerializer" class="org.springframework.data.redis.serializer.StringRedisSerializer" />
<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
<property name="connectionFactory">
<ref bean="jedisConnectionFactory" />
</property>
<property name="keySerializer">
<ref bean="stringRedisSerializer" />
</property>
<property name="hashKeySerializer">
<ref bean="stringRedisSerializer" />
</property>
</bean>
到这里,基本上redis在spring中的配置都算完成了,最多后面再加一些注入template的配置。
当我们配置完成之后,可以写一个测试方法进行测试:
首先,我们先写一个操作template的redisDto类,使用注解注入template对象
import java.io.Serializable;
import javax.annotation.Resource;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
@Component
public class RedisBase {
@Resource
private RedisTemplate<Serializable, Object> template;
/**
* @return the template
*/
public RedisTemplate getTemplate() {
return template;
}
/**
* @param template
* the template to set
*/
public void setTemplate(RedisTemplate template) {
this.template = template;
}
}
后面就简单了,可以直接在redisbase中操作redis也可以写一个接口,让我们的业务更加具体:
public interface IRedisService<String, Object> {
public void set(String key, Object value, long expiredTime) throws Exception;
public Object get(String key) throws Exception;
public void del(String key) throws Exception;
public Boolean check(String key, Object value) throws Exception;
}
有了接口,肯定的会需要实现接口的impl类,这里我用了一个抽象类来实现该接口,在用一个RedisService类来继承它:
public abstract class AbstractRedisService<String, Object> extends RedisBase implements IRedisService<String, Object> {
@Override
public void set(final String key, final Object value, final long expiredTime) {
BoundValueOperations<String,Object> valueOper = (BoundValueOperations<String, Object>) getTemplate().boundValueOps(StringUtil.trim(key));
if (expiredTime <= 0) {
valueOper.set(value);
} else {
valueOper.set(value, expiredTime, TimeUnit.MILLISECONDS);
}
}
@Override
public Object get(final String key) {
BoundValueOperations<String, Object> valueOper = (BoundValueOperations<String, Object>)getTemplate().boundValueOps(StringUtil.trim(key));
return valueOper.get();
}
@Override
public void del(String key) {
if (getTemplate().hasKey(StringUtil.trim(key))) {
getTemplate().delete(StringUtil.trim(key));
}
}
@Override
public Boolean check(String key, Object value) {
Boolean flag = false;
if (getTemplate().hasKey(StringUtil.trim(key))) {
if (value.equals(get(key))) {
flag = true;
}
}
return flag;
}
}
@Service("redisService")
public class RedisService extends AbstractRedisService<String, String> {
}
最后,我们写一个main方法来测试
public static void main(String[] args) {
@SuppressWarnings("resource")
ApplicationContext factory = new ClassPathXmlApplicationContext(
"classpath:applicationContext.xml");
RedisService rs = (RedisService) factory.getBean("redisService");
if (rs != null) {
System.out.println("RedisService : " + rs);
if (rs.check("lwj", "123456")) {
rs.set("lwj", "123456", 15000);
} else {
System.out.println("add one new key-value : lwj 123456 expire 15000");
rs.set("lwj", "1234567", 15000);
}
String value = rs.get("lwj");
System.out.println(value);
}
}
其实我是推荐大家写一个工具类就可以了。