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

1.jedis

首先,需要添加jedis:

  1. <!--jedis-->
  2. <dependency>
  3. <groupId>redis.clients</groupId>
  4. <artifactId>jedis</artifactId>
  5. <version>2.8.0</version>
  6. </dependency>

2.applicationContext-jedis.xml

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

在applicationContext-jedis.xml中添加:

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

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

  1. package redis.clients.jedis;
  2.  
  3. import java.net.URI;
  4.  
  5. import org.apache.commons.pool2.impl.GenericObjectPool;
  6. import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
  7.  
  8. import redis.clients.jedis.exceptions.JedisException;
  9. import redis.clients.util.JedisURIHelper;
  10. import redis.clients.util.Pool;
  11.  
  12. public class JedisPool extends Pool<Jedis> {
  13.  
  14. public JedisPool() {
  15. this(Protocol.DEFAULT_HOST, Protocol.DEFAULT_PORT);
  16. }
  17.  
  18. public JedisPool(final GenericObjectPoolConfig poolConfig, final String host) {
  19. this(poolConfig, host, Protocol.DEFAULT_PORT, Protocol.DEFAULT_TIMEOUT, null,
  20. Protocol.DEFAULT_DATABASE, null);
  21. }
  22.  
  23. public JedisPool(String host, int port) {
  24. this(new GenericObjectPoolConfig(), host, port, Protocol.DEFAULT_TIMEOUT, null,
  25. Protocol.DEFAULT_DATABASE, null);
  26. }
  27.  
  28. public JedisPool(final String host) {
  29. URI uri = URI.create(host);
  30. if (JedisURIHelper.isValid(uri)) {
  31. String h = uri.getHost();
  32. int port = uri.getPort();
  33. String password = JedisURIHelper.getPassword(uri);
  34. int database = JedisURIHelper.getDBIndex(uri);
  35. this.internalPool = new GenericObjectPool<Jedis>(new JedisFactory(h, port,
  36. Protocol.DEFAULT_TIMEOUT, Protocol.DEFAULT_TIMEOUT, password, database, null),
  37. new GenericObjectPoolConfig());
  38. } else {
  39. this.internalPool = new GenericObjectPool<Jedis>(new JedisFactory(host,
  40. Protocol.DEFAULT_PORT, Protocol.DEFAULT_TIMEOUT, Protocol.DEFAULT_TIMEOUT, null,
  41. Protocol.DEFAULT_DATABASE, null), new GenericObjectPoolConfig());
  42. }
  43. }
  44.  
  45. public JedisPool(final URI uri) {
  46. this(new GenericObjectPoolConfig(), uri, Protocol.DEFAULT_TIMEOUT);
  47. }
  48.  
  49. public JedisPool(final URI uri, final int timeout) {
  50. this(new GenericObjectPoolConfig(), uri, timeout);
  51. }
  52.  
  53. public JedisPool(final GenericObjectPoolConfig poolConfig, final String host, int port,
  54. int timeout, final String password) {
  55. this(poolConfig, host, port, timeout, password, Protocol.DEFAULT_DATABASE, null);
  56. }
  57.  
  58. public JedisPool(final GenericObjectPoolConfig poolConfig, final String host, final int port) {
  59. this(poolConfig, host, port, Protocol.DEFAULT_TIMEOUT, null, Protocol.DEFAULT_DATABASE, null);
  60. }
  61.  
  62. public JedisPool(final GenericObjectPoolConfig poolConfig, final String host, final int port,
  63. final int timeout) {
  64. this(poolConfig, host, port, timeout, null, Protocol.DEFAULT_DATABASE, null);
  65. }
  66.  
  67. public JedisPool(final GenericObjectPoolConfig poolConfig, final String host, int port,
  68. int timeout, final String password, final int database) {
  69. this(poolConfig, host, port, timeout, password, database, null);
  70. }
  71.  
  72. public JedisPool(final GenericObjectPoolConfig poolConfig, final String host, int port,
  73. int timeout, final String password, final int database, final String clientName) {
  74. this(poolConfig, host, port, timeout, timeout, password, database, clientName);
  75. }
  76.  
  77. public JedisPool(final GenericObjectPoolConfig poolConfig, final String host, int port,
  78. final int connectionTimeout, final int soTimeout, final String password, final int database,
  79. final String clientName) {
  80. super(poolConfig, new JedisFactory(host, port, connectionTimeout, soTimeout, password,
  81. database, clientName));
  82. }
  83.  
  84. public JedisPool(final GenericObjectPoolConfig poolConfig, final URI uri) {
  85. this(poolConfig, uri, Protocol.DEFAULT_TIMEOUT);
  86. }
  87.  
  88. public JedisPool(final GenericObjectPoolConfig poolConfig, final URI uri, final int timeout) {
  89. this(poolConfig, uri, timeout, timeout);
  90. }
  91.  
  92. public JedisPool(final GenericObjectPoolConfig poolConfig, final URI uri,
  93. final int connectionTimeout, final int soTimeout) {
  94. super(poolConfig, new JedisFactory(uri, connectionTimeout, soTimeout, null));
  95. }
  96.  
  97. @Override
  98. public Jedis getResource() {
  99. Jedis jedis = super.getResource();
  100. jedis.setDataSource(this);
  101. return jedis;
  102. }
  103.  
  104. /**
  105. * @deprecated starting from Jedis 3.0 this method will not be exposed.
  106. * Resource cleanup should be done using @see {@link redis.clients.jedis.Jedis#close()}
  107. */
  108. @Override
  109. @Deprecated
  110. public void returnBrokenResource(final Jedis resource) {
  111. if (resource != null) {
  112. returnBrokenResourceObject(resource);
  113. }
  114. }
  115.  
  116. /**
  117. * @deprecated starting from Jedis 3.0 this method will not be exposed.
  118. * Resource cleanup should be done using @see {@link redis.clients.jedis.Jedis#close()}
  119. */
  120. @Override
  121. @Deprecated
  122. public void returnResource(final Jedis resource) {
  123. if (resource != null) {
  124. try {
  125. resource.resetState();
  126. returnResourceObject(resource);
  127. } catch (Exception e) {
  128. returnBrokenResource(resource);
  129. throw new JedisException("Could not return the resource to the pool", e);
  130. }
  131. }
  132. }
  133. }

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

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

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

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

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

3.  JedisUtil

3.1 getResource

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

  1. /**
  2. * 获取资源
  3. * @return
  4. */
  5. public static Jedis getResource() {
  6. Jedis jedis = null;
  7. try {
  8. jedis = jedisPool.getResource();
  9. logger.debug("getResource:{}",jedis);
  10. } catch (Exception e) {
  11. logger.error("getResource:{}",e);
  12. if (jedis!=null)
  13. jedis.close();
  14. throw e;
  15. }
  16. return jedis;
  17. }

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

  1. public static Jedis getResource() throws JedisException {
  2. Jedis jedis = null;
  3. try {
  4. jedis = jedisPool.getResource();
  5. jedis.select(Integer.parseInt(DB_INDEX));
  6. // logger.debug("getResource.", jedis);
  7. } catch (JedisException e) {
  8. logger.warn("getResource.", e);
  9. returnBrokenResource(jedis);
  10. throw e;
  11. }
  12. return jedis;
  13. }

3.1.1设置prefix

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

  1. private static String setPrefix(String key) {
  2. key=KEY_PREFIX+"_"+key;
  3. return key;
  4. }

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

  1. public static String get(String key) {
  2. key = setPrefix(key);
  3. String value = null;
  4. Jedis jedis = null;
  5. try {
  6. jedis = getResource();
  7. if (jedis.exists(key)) {
  8. value = jedis.get(key);
  9. value = StringUtils.isNotBlank(value) && !"nil".equalsIgnoreCase(value) ? value : null;
  10. logger.debug("get {} = {}", key, value);
  11. }
  12. } catch (Exception e) {
  13. logger.warn("get {} = {}", key, value, e);
  14. } finally {
  15. returnResource(jedis);
  16. }
  17. return value;
  18. }
  1. public static String set(String key, String value, int cacheSeconds) {
  2. key = setPrefix(key);
  3. String result = null;
  4. Jedis jedis = null;
  5. try {
  6. jedis = getResource();
  7. result = jedis.set(key, value);
  8. if (cacheSeconds != 0) {
  9. jedis.expire(key, cacheSeconds);
  10. }
  11. logger.debug("set {} = {}", key, value);
  12. } catch (Exception e) {
  13. logger.warn("set {} = {}", key, value, e);
  14. } finally {
  15. returnResource(jedis);
  16. }
  17. return result;
  18. }

3.2 Object对象的缓存

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

  1. /**
  2. * 设置缓存
  3. * @param key String
  4. * @param value Object对象
  5. * @param cacheSeconds 超时时间,0为不超时
  6. * @return
  7. */
  8. public static String setObject(String key,Object value,int cacheSeconds){
  9. String result = null;
  10. Jedis jedis = null;
  11. try {
  12. jedis = getResource();
  13. result = jedis.set(getBytesKey(key),toBytes(value));
  14. if (cacheSeconds!=0){
  15. jedis.expire(key,cacheSeconds);
  16. }
  17. logger.debug("setObject {}={}",key,value);
  18. } catch (Exception e) {
  19. logger.warn("setObject {} 失败:{}",key,e);
  20. } finally {
  21. jedis.close();
  22. }
  23. return result;
  24. }
  25. /**
  26. * 获取缓存
  27. * @param key
  28. * @return 对象(反序列化)
  29. */
  30. public static Object getObject(String key){
  31. Object value = null;
  32. Jedis jedis = null;
  33. try {
  34. jedis = getResource();
  35. byte[] bytes = jedis.get(getBytesKey(key));
  36. value = toObject(bytes);
  37. logger.debug("getObject {}={}",key,value);
  38. } catch (Exception e) {
  39. logger.warn("getObject {}错误:{}",key,e.getMessage());
  40. e.printStackTrace();
  41. } finally {
  42. jedis.close();
  43. }
  44. return value;
  45. }
  46. /**
  47. * 将key转换为byte[]
  48. * @param object
  49. * @return
  50. */
  51. private static byte[] getBytesKey(Object object) {
  52. if(object instanceof String){
  53. return StringUtils.getBytes((String) object);
  54. }else {
  55. return ObjectUtils.serialize(object);
  56. }
  57. }
  58.  
  59. /**
  60. * Object转换为byte[]类型
  61. * @param value Object对象
  62. * @return byte[]数组
  63. */
  64. private static byte[] toBytes(Object value) {
  65. return ObjectUtils.serialize(value);
  66. }
  67.  
  68. /**
  69. * byte[]转换为object
  70. * @param bytes
  71. * @return
  72. */
  73. private static Object toObject(byte[] bytes) {
  74. return ObjectUtils.unserialize(bytes);
  75. }

3.3 ObjectList对象缓存

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

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

  1. /**
  2. * 获取list缓存
  3. * @param key
  4. * @return
  5. */
  6. public static List<String> getList(String key){
  7. key = addDatabaseName(key);
  8. List<String> value = null;
  9. Jedis jedis = null;
  10. try {
  11. jedis = getResource();
  12. value = jedis.lrange(key, 0, -1);
  13. logger.debug("getList {}={}",key,value);
  14. } catch (Exception e) {
  15. logger.warn("getList {}失败:{}",key,e);
  16. e.printStackTrace();
  17. } finally {
  18. jedis.close();
  19. }
  20. return value;
  21. }
  22.  
  23. /**
  24. * 获取list缓存,元素是object
  25. * @param key
  26. * @return
  27. */
  28. public static List<Object> getObjectList(String key){
  29. key = addDatabaseName(key);
  30. List<Object> value = null;
  31. Jedis jedis = null;
  32. try {
  33. jedis = getResource();
  34. List<byte[]> list = jedis.lrange(getBytesKey(key), 0, -1);
  35. value = Lists.newArrayList();
  36. for (byte[] bytes : list) {
  37. value.add(toObject(bytes));
  38. }
  39. logger.debug("getObjectList {}={}",key,value);
  40. }catch (Exception e){
  41. logger.warn("getObjectList {} 失败:{}",key,e);
  42. e.printStackTrace();
  43. }finally {
  44. jedis.close();
  45. }
  46. return value;
  47. }
  48.  
  49. /**
  50. * 设置list缓存
  51. * @param key
  52. * @param value
  53. * @param cacheSeconds
  54. * @return
  55. */
  56. public static long setList(String key,List<String> value,int cacheSeconds){
  57. key = addDatabaseName(key);
  58. long result = 0;
  59. Jedis jedis = null;
  60. try {
  61. jedis = getResource();
  62. jedis.del(key);
  63. String[] arr = new String[value.size()];
  64. value.toArray(arr);
  65. result = jedis.rpush(key,arr);
  66. if (cacheSeconds!=0){
  67. jedis.expire(key,cacheSeconds);
  68. }
  69. logger.debug("setList {}={}",key,value);
  70. }catch (Exception e){
  71. logger.warn("setList {} 错误:",key,e);
  72. e.printStackTrace();
  73. }finally {
  74. jedis.close();
  75. }
  76. return result;
  77. }
  78.  
  79. /**
  80. * 设置list缓存,list的元素为object
  81. * @param key
  82. * @param value
  83. * @param cacheSeconds
  84. * @return
  85. */
  86. public static long setObjectList(String key,List<Object> value ,int cacheSeconds){
  87. key = addDatabaseName(key);
  88. long result = 0;
  89. Jedis jedis = null;
  90. try {
  91. jedis = getResource();
  92. jedis.del(key);
  93. ArrayList<byte[]> list = Lists.newArrayList();
  94. for (Object o : value) {
  95. list.add(toBytes(o));
  96. }
  97. byte[] []arr = new byte[list.size()][];
  98. list.toArray(arr);
  99. result = jedis.rpush(getBytesKey(key),arr);
  100. if(cacheSeconds!=0){
  101. jedis.expire(key,cacheSeconds);
  102. }
  103. logger.debug("setObjectList {}={}",key,value);
  104. }catch (Exception e){
  105. logger.warn("setObjectList {} 错误:{}",key,e);
  106. e.printStackTrace();
  107. }
  108. return result;
  109. }

在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. Oracle Profile 使用

    一.目的: Oracle系统中的profile可以用来对用户所能使用的数据库资源进行限制,使用Create Profile命令创建一个Profile,用它来实现对数据库资源的限制使用,如果把该prof ...

  2. 快速学习C语言一: Hello World

    估计不会写C语言的同学也都听过C语言,从头开始快速学一下吧,以后肯定能用的上. 如果使用过其它类C的语言,如JAVA,C#等,学C的语法应该挺快的. 先快速学习并练习一些基本的语言要素,基本类型,表达 ...

  3. 解决.NET Core中MailKit无法使用阿里云邮件推送服务的问题

    在博问中(.net core怎么实现邮件发送)知道了MailKit无法使用阿里云邮件推送服务发送邮件的问题,自已实测也遇到同样的问题,而用自己搭建的邮件服务器没这个问题. 于是,向阿里云提交了工单.. ...

  4. 细心很重要---猜猜这个SQL执行的什么意思

    今天在帮客户做语句优化的时候,突然遇到这样一个语句,类似下面的例子(原语句是个update) 例子中使用AdventureWorks数据中的两个表. productID 是[Production].[ ...

  5. 《你必须知道的.NET》读书笔记二:小OO有大原则

    此篇已收录至<你必须知道的.Net>读书笔记目录贴,点击访问该目录可以获取更多内容. 一.单一职责原则 (1)核心思想:一个类最好只做一件事,只有一个引起它变化的原因 (2)常用模式:Fa ...

  6. 团队项目——站立会议 DAY11

    团队项目--站立会议 DAY11        团队成员介绍(5人):张靖颜.何玥.钟灵毓秀.赵莹.王梓萱        今日(2016/5/20),站立会议已进行了两周时间,将这一周所遇到的问题和心 ...

  7. Programming Entity Framework CodeFirst -- 约定和属性配置

     以下是EF中Data Annotation和 Fluenlt API的不同属性约定的对照.   Length Data Annotation MinLength(nn) MaxLength(nn) ...

  8. Intellij Idea 2016 配置Tomcat虚拟目录

    默认的idea是不需要配置虚拟目录了,它完全托管项目,但是有些时候,在开发过程中,是需要以虚拟目录的形式开发,即以:http://localhost:8080/虚拟目录名/index.html 这种形 ...

  9. Django集成百度富文本编辑器uEditor

    UEditor是由百度web前端研发部开发所见即所得富文本web编辑器,具有轻量,可定制,注重用户体验等特点,开源基于MIT协议,允许自由使用和修改代码. 首先从ueEditor官网下载最新版本的包, ...

  10. XMPie部署与创建过程 - 快速指南

    XMPie部署与创建过程 1PhotoShop.Indesign.VS2013关系.作用.使用 .1.1目的与过程 1. Photoshop负责导出cpkg文件. 1.1 动态性 如果你想要生成动态的 ...