在springmvc中配置jedis:
主要学习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:的更多相关文章
- 在springmvc中配置jedis(转)
主要学习https://github.com/thinkgem/jeesite.一下代码均参考于此并稍作修改. 1.jedis 首先,需要添加jedis: <!--jedis--> < ...
- Springmvc中配置Quartz使用,实现任务实时调度。
菜鸡的自我修炼,第一次接触quartz,做个记录.-------jstarseven 最近在项目中,第一次在springmvc中配置实用quartz,深刻的感受到quartz带来的方便,顺手做个记录. ...
- springmvc 中配置aop
之前自己搭建了springmvc+spring+mybaits/hibernate 的框架,并在applicationcontext.xml中配置了aop,但 发现aop根本不生效,而不用框架的话则可 ...
- SpringMVC 中配置 Swagger 插件.
一.简介 Swagger的目标是为REST API定义一个与语言无关的标准接口,允许用户发现和理解计算机服务的功能,而无需访问源代码.当通过Swagger正确定义时,用户可以用最少量的实现逻辑理解远程 ...
- springmvc中配置servlet初始化类
<bean id="InitStart" lazy-init="false" init-method="InitSystem" cl ...
- SpringMVC中配置AOP拦截controller 失效
来源:http://www.oschina.net/question/222929_124314 目测大部分同学的aop失效都是因为在springmvc的配置文件里面扫描了类,那么spring去扫描的 ...
- springmvc中配置RESTful风格控制器
一般的http请求中其实只需要get和post就可以满足项目需求了,而为什么还要使用restful可能就是为了使请求url看起来更加直观,好看吧.. restful常用的请求方式:get,post,p ...
- springmvc中配置拦截器
-------------------------------------------- 登陆controller方法 @Controller public class LoginController ...
- JavaEE开发之SpringMVC中的路由配置及参数传递详解
在之前我们使用Swift的Perfect框架来开发服务端程序时,聊到了Perfect中的路由配置.而在SpringMVC中的路由配置与其也是大同小异的.说到路由,其实就是将URL映射到Java的具体类 ...
随机推荐
- Oracle Profile 使用
一.目的: Oracle系统中的profile可以用来对用户所能使用的数据库资源进行限制,使用Create Profile命令创建一个Profile,用它来实现对数据库资源的限制使用,如果把该prof ...
- 快速学习C语言一: Hello World
估计不会写C语言的同学也都听过C语言,从头开始快速学一下吧,以后肯定能用的上. 如果使用过其它类C的语言,如JAVA,C#等,学C的语法应该挺快的. 先快速学习并练习一些基本的语言要素,基本类型,表达 ...
- 解决.NET Core中MailKit无法使用阿里云邮件推送服务的问题
在博问中(.net core怎么实现邮件发送)知道了MailKit无法使用阿里云邮件推送服务发送邮件的问题,自已实测也遇到同样的问题,而用自己搭建的邮件服务器没这个问题. 于是,向阿里云提交了工单.. ...
- 细心很重要---猜猜这个SQL执行的什么意思
今天在帮客户做语句优化的时候,突然遇到这样一个语句,类似下面的例子(原语句是个update) 例子中使用AdventureWorks数据中的两个表. productID 是[Production].[ ...
- 《你必须知道的.NET》读书笔记二:小OO有大原则
此篇已收录至<你必须知道的.Net>读书笔记目录贴,点击访问该目录可以获取更多内容. 一.单一职责原则 (1)核心思想:一个类最好只做一件事,只有一个引起它变化的原因 (2)常用模式:Fa ...
- 团队项目——站立会议 DAY11
团队项目--站立会议 DAY11 团队成员介绍(5人):张靖颜.何玥.钟灵毓秀.赵莹.王梓萱 今日(2016/5/20),站立会议已进行了两周时间,将这一周所遇到的问题和心 ...
- Programming Entity Framework CodeFirst -- 约定和属性配置
以下是EF中Data Annotation和 Fluenlt API的不同属性约定的对照. Length Data Annotation MinLength(nn) MaxLength(nn) ...
- Intellij Idea 2016 配置Tomcat虚拟目录
默认的idea是不需要配置虚拟目录了,它完全托管项目,但是有些时候,在开发过程中,是需要以虚拟目录的形式开发,即以:http://localhost:8080/虚拟目录名/index.html 这种形 ...
- Django集成百度富文本编辑器uEditor
UEditor是由百度web前端研发部开发所见即所得富文本web编辑器,具有轻量,可定制,注重用户体验等特点,开源基于MIT协议,允许自由使用和修改代码. 首先从ueEditor官网下载最新版本的包, ...
- XMPie部署与创建过程 - 快速指南
XMPie部署与创建过程 1PhotoShop.Indesign.VS2013关系.作用.使用 .1.1目的与过程 1. Photoshop负责导出cpkg文件. 1.1 动态性 如果你想要生成动态的 ...