主要学习https://github.com/thinkgem/jeesite。一下代码均参考于此并稍作修改。

1.jedis

首先,需要添加jedis:

<!--jedis-->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.8.0</version>
</dependency>

2.applicationContext-jedis.xml

然后,springmvc完成基本配置。添加jedispool的bean即可。在spring容器中添加applicationContext-jedis.xml:

在applicationContext-jedis.xml中添加:

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd">
<!-- 加载配置属性文件 -->
<context:property-placeholder ignore-unresolvable="true" location="classpath:db.properties" /> <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
<property name="maxIdle" value="300"/> <!--最大能够保持idel状态的对象数-->
<property name="maxTotal" value="60000"/><!--最大分配的对象数-->
<property name="testOnBorrow" value="true"/><!--当调用borrow Oject方法时,是否进行有效性检查-->
</bean> <bean id="jedisPool" class="redis.clients.jedis.JedisPool">
<constructor-arg index="0" ref="jedisPoolConfig"/>
<constructor-arg index="1" value="${redis.host}"/>
<constructor-arg index="2" value="${redis.port}" type="int"/>
<constructor-arg index="3" value="${redis.timeout}" type="int"/>
<constructor-arg index="4" value="${redis.auth}"/>
</bean>
</beans>

注解:参考的源码中的jedisPool配置只有三个参数:config,host,port。我复制后的结果总是getResource失败,因为我的redis添加了auth,所以猜测是不是没通过auth的原因。于是打开JedisPool的源码:

 package redis.clients.jedis;

 import java.net.URI;

 import org.apache.commons.pool2.impl.GenericObjectPool;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig; import redis.clients.jedis.exceptions.JedisException;
import redis.clients.util.JedisURIHelper;
import redis.clients.util.Pool; public class JedisPool extends Pool<Jedis> { public JedisPool() {
this(Protocol.DEFAULT_HOST, Protocol.DEFAULT_PORT);
} public JedisPool(final GenericObjectPoolConfig poolConfig, final String host) {
this(poolConfig, host, Protocol.DEFAULT_PORT, Protocol.DEFAULT_TIMEOUT, null,
Protocol.DEFAULT_DATABASE, null);
} public JedisPool(String host, int port) {
this(new GenericObjectPoolConfig(), host, port, Protocol.DEFAULT_TIMEOUT, null,
Protocol.DEFAULT_DATABASE, null);
} public JedisPool(final String host) {
URI uri = URI.create(host);
if (JedisURIHelper.isValid(uri)) {
String h = uri.getHost();
int port = uri.getPort();
String password = JedisURIHelper.getPassword(uri);
int database = JedisURIHelper.getDBIndex(uri);
this.internalPool = new GenericObjectPool<Jedis>(new JedisFactory(h, port,
Protocol.DEFAULT_TIMEOUT, Protocol.DEFAULT_TIMEOUT, password, database, null),
new GenericObjectPoolConfig());
} else {
this.internalPool = new GenericObjectPool<Jedis>(new JedisFactory(host,
Protocol.DEFAULT_PORT, Protocol.DEFAULT_TIMEOUT, Protocol.DEFAULT_TIMEOUT, null,
Protocol.DEFAULT_DATABASE, null), new GenericObjectPoolConfig());
}
} public JedisPool(final URI uri) {
this(new GenericObjectPoolConfig(), uri, Protocol.DEFAULT_TIMEOUT);
} public JedisPool(final URI uri, final int timeout) {
this(new GenericObjectPoolConfig(), uri, timeout);
} public JedisPool(final GenericObjectPoolConfig poolConfig, final String host, int port,
int timeout, final String password) {
this(poolConfig, host, port, timeout, password, Protocol.DEFAULT_DATABASE, null);
} public JedisPool(final GenericObjectPoolConfig poolConfig, final String host, final int port) {
this(poolConfig, host, port, Protocol.DEFAULT_TIMEOUT, null, Protocol.DEFAULT_DATABASE, null);
} public JedisPool(final GenericObjectPoolConfig poolConfig, final String host, final int port,
final int timeout) {
this(poolConfig, host, port, timeout, null, Protocol.DEFAULT_DATABASE, null);
} public JedisPool(final GenericObjectPoolConfig poolConfig, final String host, int port,
int timeout, final String password, final int database) {
this(poolConfig, host, port, timeout, password, database, null);
} public JedisPool(final GenericObjectPoolConfig poolConfig, final String host, int port,
int timeout, final String password, final int database, final String clientName) {
this(poolConfig, host, port, timeout, timeout, password, database, clientName);
} public JedisPool(final GenericObjectPoolConfig poolConfig, final String host, int port,
final int connectionTimeout, final int soTimeout, final String password, final int database,
final String clientName) {
super(poolConfig, new JedisFactory(host, port, connectionTimeout, soTimeout, password,
database, clientName));
} public JedisPool(final GenericObjectPoolConfig poolConfig, final URI uri) {
this(poolConfig, uri, Protocol.DEFAULT_TIMEOUT);
} public JedisPool(final GenericObjectPoolConfig poolConfig, final URI uri, final int timeout) {
this(poolConfig, uri, timeout, timeout);
} public JedisPool(final GenericObjectPoolConfig poolConfig, final URI uri,
final int connectionTimeout, final int soTimeout) {
super(poolConfig, new JedisFactory(uri, connectionTimeout, soTimeout, null));
} @Override
public Jedis getResource() {
Jedis jedis = super.getResource();
jedis.setDataSource(this);
return jedis;
} /**
* @deprecated starting from Jedis 3.0 this method will not be exposed.
* Resource cleanup should be done using @see {@link redis.clients.jedis.Jedis#close()}
*/
@Override
@Deprecated
public void returnBrokenResource(final Jedis resource) {
if (resource != null) {
returnBrokenResourceObject(resource);
}
} /**
* @deprecated starting from Jedis 3.0 this method will not be exposed.
* Resource cleanup should be done using @see {@link redis.clients.jedis.Jedis#close()}
*/
@Override
@Deprecated
public void returnResource(final Jedis resource) {
if (resource != null) {
try {
resource.resetState();
returnResourceObject(resource);
} catch (Exception e) {
returnBrokenResource(resource);
throw new JedisException("Could not return the resource to the pool", e);
}
}
}
}

看到有password的参数配置,如果没有配置的话默认为null。到这一步我便没有往下深入看了,因为我连接的redis中有auth,原谅我的不求甚解。于是,我接着配置timeout和auth。timeout直接还是源码的默认值。后面的代码测试通过。在这里我了解到spring的bean注入的几个参数含义:比如property表示属性注入,constructor表示构造函数的参数注入。

为了更清楚的表达,redis要设置db,配置文件参数也做一下改动:

<bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
<property name="maxIdle" value="300" /> <!-- 最大能够保持idel状态的对象数 -->
<property name="maxTotal" value="60000" /> <!-- 最大分配的对象数 -->
<property name="testOnBorrow" value="true" /> <!-- 当调用borrow Object方法时,是否进行有效性检查 -->
</bean> <bean id="jedisPool" class="redis.clients.jedis.JedisPool">
<constructor-arg name="poolConfig" ref="jedisPoolConfig" />
<constructor-arg name="host" value="${redis.host}" />
<constructor-arg name="port" value="${redis.port}" type="int" />
<constructor-arg name="timeout" value="${redis.timeout}" type="int" />
<constructor-arg name="password" value="#{'${redis.password}'!=''?'${redis.password}':null}" />
<constructor-arg name="database" value="${redis.db.index}" type="int" />
</bean>

最后一项参数是选择redis的db,我认为通常默认连接的都是redis的0,那么我们的开发环境为了不冲突,应该另外设置。但JedisPool并没有只有指定db的构造函数,所以选择了这个构造函数。唯一的问题是,默认我们的redis是没有密码的,那么这里也填null而不是空字符串哦。所以,这里使用spring spEL表达式来填充空。对应的配置文件如下:

#redis settings
redis.keyPrefix=wz
redis.host=127.0.0.1
redis.port=
redis.timeout=
#注意,如果没有password,此处不设置值,但这一项要保留
redis.password=
redis.db.index=

3.  JedisUtil

3.1 getResource

上面设置好了JedisPool,这里就要获取jedis。然后就可以利用jedis进行操作了。

  /**
* 获取资源
* @return
*/
public static Jedis getResource() {
Jedis jedis = null;
try {
jedis = jedisPool.getResource();
logger.debug("getResource:{}",jedis);
} catch (Exception e) {
logger.error("getResource:{}",e);
if (jedis!=null)
jedis.close();
throw e;
}
return jedis;
}

但是,为了更加自定义的设置db,这里也可以加一个db的选择:

    public static Jedis getResource() throws JedisException {
Jedis jedis = null;
try {
jedis = jedisPool.getResource();
jedis.select(Integer.parseInt(DB_INDEX));
// logger.debug("getResource.", jedis);
} catch (JedisException e) {
logger.warn("getResource.", e);
returnBrokenResource(jedis);
throw e;
}
return jedis;
}

3.1.1设置prefix

为了我们的key与其他app不冲突,我们最后为我们key统一增加一个标识,这种做法类似选择一个表。

private static String setPrefix(String key) {
key=KEY_PREFIX+"_"+key;
return key;
}

在任何使用到redis的地方,配置key的prefix。比如get 和 set:

    public static String get(String key) {
key = setPrefix(key);
String value = null;
Jedis jedis = null;
try {
jedis = getResource();
if (jedis.exists(key)) {
value = jedis.get(key);
value = StringUtils.isNotBlank(value) && !"nil".equalsIgnoreCase(value) ? value : null;
logger.debug("get {} = {}", key, value);
}
} catch (Exception e) {
logger.warn("get {} = {}", key, value, e);
} finally {
returnResource(jedis);
}
return value;
}
    public static String set(String key, String value, int cacheSeconds) {
key = setPrefix(key);
String result = null;
Jedis jedis = null;
try {
jedis = getResource();
result = jedis.set(key, value);
if (cacheSeconds != 0) {
jedis.expire(key, cacheSeconds);
}
logger.debug("set {} = {}", key, value);
} catch (Exception e) {
logger.warn("set {} = {}", key, value, e);
} finally {
returnResource(jedis);
}
return result;
}

3.2 Object对象的缓存

通过使用jedis基本可以完成任何操作了。这里添加一个缓存对象的功能。java对象的缓存利用序列化实现,因此,需要缓存的对象必须实现了serializable接口。关于如何序列化,参考:将对象序列化和反序列化

   /**
* 设置缓存
* @param key String
* @param value Object对象
* @param cacheSeconds 超时时间,0为不超时
* @return
*/
public static String setObject(String key,Object value,int cacheSeconds){
String result = null;
Jedis jedis = null;
try {
jedis = getResource();
result = jedis.set(getBytesKey(key),toBytes(value));
if (cacheSeconds!=0){
jedis.expire(key,cacheSeconds);
}
logger.debug("setObject {}={}",key,value);
} catch (Exception e) {
logger.warn("setObject {} 失败:{}",key,e);
} finally {
jedis.close();
}
return result;
}
/**
* 获取缓存
* @param key
* @return 对象(反序列化)
*/
public static Object getObject(String key){
Object value = null;
Jedis jedis = null;
try {
jedis = getResource();
byte[] bytes = jedis.get(getBytesKey(key));
value = toObject(bytes);
logger.debug("getObject {}={}",key,value);
} catch (Exception e) {
logger.warn("getObject {}错误:{}",key,e.getMessage());
e.printStackTrace();
} finally {
jedis.close();
}
return value;
}
/**
* 将key转换为byte[]
* @param object
* @return
*/
private static byte[] getBytesKey(Object object) {
if(object instanceof String){
return StringUtils.getBytes((String) object);
}else {
return ObjectUtils.serialize(object);
}
} /**
* Object转换为byte[]类型
* @param value Object对象
* @return byte[]数组
*/
private static byte[] toBytes(Object value) {
return ObjectUtils.serialize(value);
} /**
* byte[]转换为object
* @param bytes
* @return
*/
private static Object toObject(byte[] bytes) {
return ObjectUtils.unserialize(bytes);
}

3.3 ObjectList对象缓存

我们平时用到的list基本都是ObjectList,即list的元素为object而不是String。这样就需要特定方法来缓存了。

采用同样的方式,将object序列化为字节数组,然后存储起来。取出的时候再反序列化,因此object必须实现了serializable接口,而且static的成员不能序列化或者说序列化的结果为默认值。原因参考:将对象序列化和反序列化

 /**
* 获取list缓存
* @param key
* @return
*/
public static List<String> getList(String key){
key = addDatabaseName(key);
List<String> value = null;
Jedis jedis = null;
try {
jedis = getResource();
value = jedis.lrange(key, 0, -1);
logger.debug("getList {}={}",key,value);
} catch (Exception e) {
logger.warn("getList {}失败:{}",key,e);
e.printStackTrace();
} finally {
jedis.close();
}
return value;
} /**
* 获取list缓存,元素是object
* @param key
* @return
*/
public static List<Object> getObjectList(String key){
key = addDatabaseName(key);
List<Object> value = null;
Jedis jedis = null;
try {
jedis = getResource();
List<byte[]> list = jedis.lrange(getBytesKey(key), 0, -1);
value = Lists.newArrayList();
for (byte[] bytes : list) {
value.add(toObject(bytes));
}
logger.debug("getObjectList {}={}",key,value);
}catch (Exception e){
logger.warn("getObjectList {} 失败:{}",key,e);
e.printStackTrace();
}finally {
jedis.close();
}
return value;
} /**
* 设置list缓存
* @param key
* @param value
* @param cacheSeconds
* @return
*/
public static long setList(String key,List<String> value,int cacheSeconds){
key = addDatabaseName(key);
long result = 0;
Jedis jedis = null;
try {
jedis = getResource();
jedis.del(key);
String[] arr = new String[value.size()];
value.toArray(arr);
result = jedis.rpush(key,arr);
if (cacheSeconds!=0){
jedis.expire(key,cacheSeconds);
}
logger.debug("setList {}={}",key,value);
}catch (Exception e){
logger.warn("setList {} 错误:",key,e);
e.printStackTrace();
}finally {
jedis.close();
}
return result;
} /**
* 设置list缓存,list的元素为object
* @param key
* @param value
* @param cacheSeconds
* @return
*/
public static long setObjectList(String key,List<Object> value ,int cacheSeconds){
key = addDatabaseName(key);
long result = 0;
Jedis jedis = null;
try {
jedis = getResource();
jedis.del(key);
ArrayList<byte[]> list = Lists.newArrayList();
for (Object o : value) {
list.add(toBytes(o));
}
byte[] []arr = new byte[list.size()][];
list.toArray(arr);
result = jedis.rpush(getBytesKey(key),arr);
if(cacheSeconds!=0){
jedis.expire(key,cacheSeconds);
}
logger.debug("setObjectList {}={}",key,value);
}catch (Exception e){
logger.warn("setObjectList {} 错误:{}",key,e);
e.printStackTrace();
}
return result;
}

在springmvc中配置jedis:的更多相关文章

  1. 在springmvc中配置jedis(转)

    主要学习https://github.com/thinkgem/jeesite.一下代码均参考于此并稍作修改. 1.jedis 首先,需要添加jedis: <!--jedis--> < ...

  2. Springmvc中配置Quartz使用,实现任务实时调度。

    菜鸡的自我修炼,第一次接触quartz,做个记录.-------jstarseven 最近在项目中,第一次在springmvc中配置实用quartz,深刻的感受到quartz带来的方便,顺手做个记录. ...

  3. springmvc 中配置aop

    之前自己搭建了springmvc+spring+mybaits/hibernate 的框架,并在applicationcontext.xml中配置了aop,但 发现aop根本不生效,而不用框架的话则可 ...

  4. SpringMVC 中配置 Swagger 插件.

    一.简介 Swagger的目标是为REST API定义一个与语言无关的标准接口,允许用户发现和理解计算机服务的功能,而无需访问源代码.当通过Swagger正确定义时,用户可以用最少量的实现逻辑理解远程 ...

  5. springmvc中配置servlet初始化类

    <bean  id="InitStart" lazy-init="false" init-method="InitSystem" cl ...

  6. SpringMVC中配置AOP拦截controller 失效

    来源:http://www.oschina.net/question/222929_124314 目测大部分同学的aop失效都是因为在springmvc的配置文件里面扫描了类,那么spring去扫描的 ...

  7. springmvc中配置RESTful风格控制器

    一般的http请求中其实只需要get和post就可以满足项目需求了,而为什么还要使用restful可能就是为了使请求url看起来更加直观,好看吧.. restful常用的请求方式:get,post,p ...

  8. springmvc中配置拦截器

    -------------------------------------------- 登陆controller方法 @Controller public class LoginController ...

  9. JavaEE开发之SpringMVC中的路由配置及参数传递详解

    在之前我们使用Swift的Perfect框架来开发服务端程序时,聊到了Perfect中的路由配置.而在SpringMVC中的路由配置与其也是大同小异的.说到路由,其实就是将URL映射到Java的具体类 ...

随机推荐

  1. wordpress搬家换域名

    很多朋友开始接触wordpress都是在本地安装调试好了,再上传到服务器正常运营,我也是一样当我在本地测试好了准备将网站上线,在搬家到服务器的时候遇到过的一些问题,记录分享一下我是如何为wordpre ...

  2. PAT/图形输出习题集

    B1027. 打印沙漏 (20) Description: 本题要求你写个程序把给定的符号打印成沙漏的形状.例如给定17个"*",要求按下列格式打印 ***** *** * *** ...

  3. Ubuntu全新安装firefox最新版本

    Ubuntu默认安装firefox,但是自带的软件仓库是不会随firefox更新的,我在使用中老是提示flash插件需要激活,提示中可选的解决方式有三种 1.更新flash插件,但是跳转到adobe的 ...

  4. EF(Linq)框架使用过程中的小技巧汇总

    这篇博客总结本人在实际项目中遇到的一些关于EF或者Linq的问题,作为以后复习的笔记或者供后来人参考(遇到问题便更新). 目录 技巧1: DbFunctions.TruncateTime()的使用 技 ...

  5. Java设计模式5:原型模式

    原型模式 原型模式属于对象的创建模式,通过给出一个原型对象来指明所有创建的对象的类型,然后用复制这个原型对象的办法创建出更多同类型的对象,这就是原型模式的用意. 原型模式结构 原型模式要求对象实现一个 ...

  6. python--批量下载豆瓣图片

    溜达豆瓣的时候,发现一些图片,懒得一个一个扒,之前写过c#和python版本的图片下载,因此拿之前的Python代码来改了改,折腾出一个豆瓣版本,方便各位使用 # -*- coding:utf8 -* ...

  7. 使用Guava提供的transform批量转换

    实际开发了,为了快速查询,我们会把日期以Long类型的方式存储到数据库中,比如20000000000000L,但显示的时候,要完整的日期,即yyyy-MM-dd的格式显示. 这个时候,我们就可以使用C ...

  8. .NET在线培训 | C#在线培训 | .NET培训 | 最课程培训

    最课程(www.zuikc.com) 软件开发培训,在线软件培训的创新者!我们的创新在于: 1:一次购买,终身服务.每个最课程学员都会分配一位专职教师及一位监管教师,点对点跟进课程进度,直到您学会课程 ...

  9. 基于Task的异步模式的定义

    返回该系列目录<基于Task的异步模式--全面介绍> 命名,参数和返回类型 在TAP(Task-based Asynchronous Pattern)中的异步操作的启动和完成是通过一个单独 ...

  10. 爱上MVC~在Views的多级文件夹~续~分部页的支持

    回到目录 之前写的一篇文章,主要针对View视图,它可以放在N级目录下,不必须非要在views/controller/action这种关系了,而在程序运行过程中,发现分页视图对本功能并不支持,原因很简 ...