spring+redis集成,策略设计,灵活配置,支持单机和集群

来源:互联网 发布:小班教案防火知多少 编辑:程序博客网 时间:2024/05/16 01:23

spring+redis集成,策略设计,支持单机和集群

前言

单JVM保证并发数据安全1.线程同步锁,synchronized(this)或者Lock接口2.数据表增加版本号字段,update where条件后面跟上版本号.这样就只会更新一次3.利用数据库特性,悲观锁,性能较低,不推荐
这里主要用redis作缓存,实现分布式集群业务锁(多JVM环境)

环境准备

博主一惯基于自己ssm项目在做整合.可谓是大杂烩,后期还会逐步添加各种javaEE技术目前是spring+springmvc+mybatis+redis+actvemq+dubbo+redis+log4j+quartz还有很多细节未处理,大家见谅,项目可以运行,一切正常,已测试.请注意本地需要activemq,redis环境.如果集成dubbo,还需要zookeeper作注册中心技术交流可以加QQ757617714github地址:https://github.com/15000814726/ssm.git

pom.xml导入依赖

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">  <modelVersion>4.0.0</modelVersion>  <groupId>com.ssm.demo</groupId>  <artifactId>ssm</artifactId>  <packaging>war</packaging>  <version>0.0.1-SNAPSHOT</version>  <name>ssm</name>  <url>http://maven.apache.org</url>  <properties>          <!-- spring版本号 -->          <spring.version>4.0.2.RELEASE</spring.version>          <!-- mybatis版本号 -->          <mybatis.version>3.2.6</mybatis.version>          <!-- log4j日志文件管理包版本 -->          <slf4j.version>1.7.7</slf4j.version>          <log4j.version>1.2.17</log4j.version>        <!-- activemq -->        <activemq_version>5.11.1</activemq_version>        <!-- quartz -->        <quartz.version>2.2.1</quartz.version>         <!-- dubbo -->        <dubbo.version>2.5.3</dubbo.version>        <!-- jedis -->        <jedis.version>2.8.1</jedis.version>    </properties>      <dependencies>          <dependency>              <groupId>junit</groupId>              <artifactId>junit</artifactId>              <version>4.11</version>              <!-- 表示开发的时候引入,发布的时候不会加载此包 -->              <scope>test</scope>          </dependency>          <!-- spring核心包 -->          <dependency>              <groupId>org.springframework</groupId>              <artifactId>spring-core</artifactId>              <version>${spring.version}</version>          </dependency>        <dependency>              <groupId>org.springframework</groupId>              <artifactId>spring-beans</artifactId>              <version>${spring.version}</version>          </dependency>          <!-- 添加扫描javabean的注解包 -->        <dependency>              <groupId>org.springframework</groupId>              <artifactId>spring-orm</artifactId>              <version>${spring.version}</version>          </dependency>        <!-- web-mvc依赖web,不用导包 -->        <!-- <dependency>              <groupId>org.springframework</groupId>              <artifactId>spring-web</artifactId>              <version>${spring.version}</version>          </dependency> -->          <dependency>              <groupId>org.springframework</groupId>              <artifactId>spring-oxm</artifactId>              <version>${spring.version}</version>            <!-- 排除依赖 -->            <exclusions>                  <exclusion>                      <groupId>org.springframework</groupId>                      <artifactId>spring-beans</artifactId>                  </exclusion>              </exclusions>         </dependency>          <dependency>              <groupId>org.springframework</groupId>              <artifactId>spring-tx</artifactId>              <version>${spring.version}</version>              <!-- 排除依赖 -->            <exclusions>                  <exclusion>                      <groupId>org.springframework</groupId>                      <artifactId>spring-beans</artifactId>                  </exclusion>              </exclusions>        </dependency>          <dependency>              <groupId>org.springframework</groupId>              <artifactId>spring-jdbc</artifactId>              <version>${spring.version}</version>            <!-- 排除依赖 -->            <exclusions>                  <exclusion>                      <groupId>org.springframework</groupId>                      <artifactId>spring-beans</artifactId>                  </exclusion>              </exclusions>          </dependency>          <dependency>              <groupId>org.springframework</groupId>              <artifactId>spring-webmvc</artifactId>              <version>${spring.version}</version>              <!-- 排除依赖 -->            <exclusions>                  <exclusion>                      <groupId>org.springframework</groupId>                      <artifactId>spring-beans</artifactId>                  </exclusion>              </exclusions>         </dependency>          <dependency>              <groupId>org.springframework</groupId>              <artifactId>spring-aop</artifactId>              <version>${spring.version}</version>              <exclusions>                  <exclusion>                      <groupId>org.springframework</groupId>                      <artifactId>spring-beans</artifactId>                  </exclusion>              </exclusions>         </dependency>          <dependency>              <groupId>org.springframework</groupId>              <artifactId>spring-context-support</artifactId>              <version>${spring.version}</version>              <exclusions>                  <exclusion>                      <groupId>org.springframework</groupId>                      <artifactId>spring-beans</artifactId>                  </exclusion>              </exclusions>        </dependency>          <dependency>              <groupId>org.springframework</groupId>              <artifactId>spring-jms</artifactId>              <version>${spring.version}</version>          </dependency>        <dependency>              <groupId>org.springframework</groupId>              <artifactId>spring-test</artifactId>              <version>${spring.version}</version>          </dependency>          <!-- mybatis核心包 -->          <dependency>              <groupId>org.mybatis</groupId>              <artifactId>mybatis</artifactId>              <version>${mybatis.version}</version>          </dependency>          <!-- mybatis/spring包 -->          <dependency>              <groupId>org.mybatis</groupId>              <artifactId>mybatis-spring</artifactId>              <version>1.2.2</version>          </dependency>          <!-- 导入java ee jar 包 -->          <dependency>              <groupId>javax</groupId>              <artifactId>javaee-api</artifactId>              <version>7.0</version>          </dependency>          <!-- 导入Mysql数据库链接jar包 -->          <dependency>              <groupId>mysql</groupId>              <artifactId>mysql-connector-java</artifactId>              <version>5.1.30</version>          </dependency>          <!-- 数据库连接池2选一,还有其余的 -->        <!-- dbcp连接池 -->          <dependency>              <groupId>commons-dbcp</groupId>              <artifactId>commons-dbcp</artifactId>              <version>1.2.2</version>            <exclusions>                  <exclusion>                      <groupId>commons-pool</groupId>                      <artifactId>commons-pool</artifactId>                  </exclusion>             </exclusions>          </dependency>             <!-- c3p0连接池 -->        <dependency>            <groupId>com.mchange</groupId>            <artifactId>c3p0</artifactId>            <version>0.9.5.2</version>        </dependency>        <!-- JSTL标签类 -->          <dependency>              <groupId>jstl</groupId>              <artifactId>jstl</artifactId>              <version>1.2</version>          </dependency>          <!-- 日志文件管理包 -->          <dependency>              <groupId>log4j</groupId>              <artifactId>log4j</artifactId>              <version>${log4j.version}</version>          </dependency>           <dependency>              <groupId>org.slf4j</groupId>              <artifactId>slf4j-api</artifactId>              <version>${slf4j.version}</version>          </dependency>          <dependency>              <groupId>org.slf4j</groupId>              <artifactId>slf4j-log4j12</artifactId>              <version>${slf4j.version}</version>          </dependency>          <!-- fastjson -->        <dependency>            <groupId>com.alibaba</groupId>            <artifactId>fastjson</artifactId>            <version>1.2.17</version>        </dependency>        <!-- Jackson -->          <dependency>            <groupId>com.fasterxml.jackson.core</groupId>            <artifactId>jackson-databind</artifactId>            <version>2.5.3</version>        </dependency>         <dependency>            <groupId>org.codehaus.jackson</groupId>            <artifactId>jackson-mapper-asl</artifactId>            <version>1.9.13</version>        </dependency>        <!-- 上传组件包 -->          <dependency>              <groupId>commons-fileupload</groupId>              <artifactId>commons-fileupload</artifactId>              <version>1.3.1</version>          </dependency>          <dependency>              <groupId>commons-io</groupId>              <artifactId>commons-io</artifactId>              <version>2.4</version>          </dependency>          <dependency>              <groupId>commons-codec</groupId>              <artifactId>commons-codec</artifactId>              <version>1.9</version>          </dependency>          <!-- StringUtils -->        <dependency>            <groupId>org.apache.commons</groupId>            <artifactId>commons-lang3</artifactId>            <version>3.4</version>        </dependency>        <!-- 集合工具类 -->        <dependency>            <groupId>commons-collections</groupId>            <artifactId>commons-collections</artifactId>            <version>3.2.1</version>        </dependency>        <!-- activeMQ -->        <dependency>              <groupId>org.apache.activemq</groupId>              <artifactId>activemq-all</artifactId>              <version>${activemq_version}</version>          </dependency>        <dependency>              <groupId>org.apache.activemq</groupId>              <artifactId>activemq-pool</artifactId>              <version>${activemq_version}</version>            <!-- <exclusions>                  <exclusion>                      <groupId>commons-pool</groupId>                      <artifactId>commons-pool</artifactId>                  </exclusion>              </exclusions> -->          </dependency>        <dependency>            <groupId>org.apache.xbean</groupId>            <artifactId>xbean-spring</artifactId>            <version>3.16</version>        </dependency>        <!-- Quartz 定时任务 -->          <dependency>              <groupId>org.quartz-scheduler</groupId>              <artifactId>quartz</artifactId>              <version>${quartz.version}</version>            <!-- 排除依赖 -->            <exclusions>                  <exclusion>                      <groupId>c3p0</groupId>                      <artifactId>c3p0</artifactId>                  </exclusion>              </exclusions>          </dependency>         <dependency>            <groupId>org.quartz-scheduler</groupId>            <artifactId>quartz-jobs</artifactId>            <version>${quartz.version}</version>        </dependency>        <!-- dubbo -->        <dependency>            <groupId>com.alibaba</groupId>            <artifactId>dubbo</artifactId>            <version>${dubbo.version}</version>            <exclusions>                  <exclusion>                      <artifactId>spring</artifactId>                      <groupId>org.springframework</groupId>                  </exclusion>              </exclusions>        </dependency>        <!-- zookeeper -->        <dependency>            <groupId>org.apache.zookeeper</groupId>            <artifactId>zookeeper</artifactId>            <version>3.4.7</version>        </dependency>        <dependency>            <groupId>com.101tec</groupId>            <artifactId>zkclient</artifactId>            <version>0.9</version>        </dependency>        <!-- jedis -->        <dependency>              <groupId>redis.clients</groupId>              <artifactId>jedis</artifactId>              <version>${jedis.version}</version>             <!-- <exclusions>                  <exclusion>                      <groupId>org.apache.commons</groupId>                      <artifactId>commons-pool2</artifactId>                  </exclusion>              </exclusions> -->        </dependency>          <!-- fst序列化工具 -->        <dependency>            <groupId>de.ruedigermoeller</groupId>            <artifactId>fst</artifactId>            <version>2.45</version>            <exclusions>                  <exclusion>                      <groupId>com.fasterxml.jackson.core</groupId>                      <artifactId>jackson-core</artifactId>                  </exclusion>                <exclusion>                      <groupId>org.javassist</groupId>                      <artifactId>javassist</artifactId>                  </exclusion>            </exclusions>        </dependency>        <!-- guava操作集合 -->        <dependency>            <groupId>com.google.guava</groupId>            <artifactId>guava</artifactId>            <version>21.0</version>        </dependency>    </dependencies>    <build>        <finalName>ssm</finalName>        <plugins>            <!-- 配置Tomcat插件 -->            <!-- <plugin>                <groupId>org.apache.tomcat.maven</groupId>                <artifactId>tomcat7-maven-plugin</artifactId>                <version>2.2</version>                <configuration>                    <port>8082</port>                    <path>/</path>                </configuration>            </plugin> -->            <!-- <plugin>                <groupId>org.apache.tomcat.maven</groupId>                <artifactId>tomcat7-maven-plugin</artifactId>                <configuration>                    <server>tomcat-local</server>                    <port>8086</port>                    <contextReloadable>true</contextReloadable>                    <systemProperties>                         <JAVA_OPTS>-Xms1024m -Xmx1024m -XX:PermSize=128M - XX:MaxPermSize=256m</JAVA_OPTS>                    </systemProperties>                </configuration>            </plugin> -->            <!-- 资源文件拷贝插件 -->            <plugin>                <groupId>org.apache.maven.plugins</groupId>                <artifactId>maven-resources-plugin</artifactId>                <version>2.7</version>                <configuration>                    <encoding>UTF-8</encoding>                </configuration>            </plugin>            <!-- java编译插件 -->            <plugin>                <groupId>org.apache.maven.plugins</groupId>                <artifactId>maven-compiler-plugin</artifactId>                <version>3.2</version>                <configuration>                    <source>1.7</source>                    <target>1.7</target>                    <encoding>UTF-8</encoding>                </configuration>            </plugin>        </plugins>    </build></project>

Servlet容器入口web.xml

只在web.xml加载spring.xml.整合的XML在spring.xml引入.给人感觉赏心悦目,养成搭建习惯
<?xml version="1.0" encoding="UTF-8"?>  <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"      xmlns="http://java.sun.com/xml/ns/javaee"      xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"      version="3.0">      <display-name>ssm</display-name>      <!-- 加载spring容器管理的所有bean -->      <context-param>          <param-name>contextConfigLocation</param-name>          <param-value>classpath:spring.xml</param-value>      </context-param>    <!-- 编码过滤器 -->      <filter>          <filter-name>encodingFilter</filter-name>          <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>          <async-supported>true</async-supported>          <init-param>              <param-name>encoding</param-name>              <param-value>UTF-8</param-value>          </init-param>      </filter>      <filter-mapping>          <filter-name>encodingFilter</filter-name>          <url-pattern>/*</url-pattern>      </filter-mapping>    <!-- Spring监听器 -->      <listener>          <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>      </listener>    <!-- 防止Spring内存溢出监听器 -->      <listener>          <listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class>      </listener>      <!-- Spring MVC servlet -->      <servlet>          <servlet-name>SpringMVC</servlet-name>          <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>          <init-param>              <param-name>contextConfigLocation</param-name>              <param-value>classpath:spring-mvc.xml</param-value>          </init-param>          <load-on-startup>1</load-on-startup>          <async-supported>true</async-supported>      </servlet>      <servlet-mapping>          <servlet-name>SpringMVC</servlet-name>          <!-- 此处可以可以配置成*.do,对应struts的后缀习惯 -->          <url-pattern>/</url-pattern>      </servlet-mapping>    <welcome-file-list>          <welcome-file>/index.jsp</welcome-file>      </welcome-file-list>  </web-app>

spring容器核心配置文件和properties文件

spring.xml

<?xml version="1.0" encoding="UTF-8"?><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"     xmlns:task="http://www.springframework.org/schema/task"    xsi:schemaLocation="        http://www.springframework.org/schema/beans         http://www.springframework.org/schema/beans/spring-beans-4.0.xsd         http://www.springframework.org/schema/context         http://www.springframework.org/schema/context/spring-context-4.0.xsd        http://www.springframework.org/schema/task         http://www.springframework.org/schema/task/spring-task-4.0.xsd ">    <!-- 自动扫描 -->      <context:component-scan base-package="com.ssm" />    <!-- 引入配置文件 -->      <bean id="propertyConfigurer"  class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">          <property name="locations">            <list>                <value>classpath:redis.properties</value>                <value>classpath:jdbc.properties</value>                <value>classpath:log4j.properties</value>            </list>        </property>      </bean>      <!-- 引入activemq -->    <import resource="spring-active.xml"/>    <!-- 引入mvc -->    <import resource="spring-mvc.xml"/>    <!-- 引入mybatis -->    <import resource="spring-mybatis.xml"/>    <!-- 引入redis -->    <import resource="spring-redis.xml"/>    <!-- 引入定时任务 --><!-- job会不停的打日志,先注释掉,放开JOB就会跑 -->    <!-- <import resource="spring-quartz.xml"/> --></beans>        

spring-mybatis.xml

<?xml version="1.0" encoding="UTF-8"?>  <beans xmlns="http://www.springframework.org/schema/beans"      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"     xmlns:p="http://www.springframework.org/schema/p"      xmlns:context="http://www.springframework.org/schema/context"      xmlns:mvc="http://www.springframework.org/schema/mvc"      xsi:schemaLocation="http://www.springframework.org/schema/beans                            http://www.springframework.org/schema/beans/spring-beans-3.1.xsd                            http://www.springframework.org/schema/context                            http://www.springframework.org/schema/context/spring-context-3.1.xsd                            http://www.springframework.org/schema/mvc                            http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd">      <!-- dbcp连接池 -->    <!-- <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"          destroy-method="close">          <property name="driverClassName" value="${driver}" />          <property name="url" value="${url}" />          <property name="username" value="${username}" />          <property name="password" value="${password}" />          <property name="initialSize" value="${initialSize}"></property>          <property name="maxActive" value="${maxActive}"></property>          <property name="maxIdle" value="${maxIdle}"></property>          <property name="minIdle" value="${minIdle}"></property>          <property name="maxWait" value="${maxWait}"></property>      </bean> -->    <!-- C3P0连接池 -->    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">          <property name="driverClass" value="${driver}" />          <property name="jdbcUrl" value="${url}" />          <property name="user" value="${username}" />          <property name="password" value="${password}" />          <property name="initialPoolSize" value="${initialSize}" />          <property name="minPoolSize" value="${minIdle}" />          <property name="maxPoolSize" value="${maxActive}" />          <property name="testConnectionOnCheckin" value="false" />          <property name="idleConnectionTestPeriod" value="60" />          <property name="checkoutTimeout" value="30000" />          <property name="preferredTestQuery" value="select now()" />      </bean>     <!-- spring和MyBatis完美整合,不需要mybatis的配置映射文件 -->      <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">          <property name="dataSource" ref="dataSource" />          <!-- 自动扫描mapping.xml文件 -->          <property name="mapperLocations" value="classpath:com/ssm/mappings/*apper.xml"></property>      </bean>      <!-- DAO接口所在包名,Spring会自动查找其下的类 -->      <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">          <property name="basePackage" value="com.ssm.dao" />          <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property>      </bean>      <!-- 事务管理 -->      <bean id="transactionManager"          class="org.springframework.jdbc.datasource.DataSourceTransactionManager">          <property name="dataSource" ref="dataSource" />      </bean>  </beans> 

spring-mvc.xml

<?xml version="1.0" encoding="UTF-8"?>  <beans xmlns="http://www.springframework.org/schema/beans"      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"     xmlns:p="http://www.springframework.org/schema/p"      xmlns:context="http://www.springframework.org/schema/context"      xmlns:mvc="http://www.springframework.org/schema/mvc"      xsi:schemaLocation="http://www.springframework.org/schema/beans                            http://www.springframework.org/schema/beans/spring-beans-3.1.xsd                            http://www.springframework.org/schema/context                            http://www.springframework.org/schema/context/spring-context-3.1.xsd                            http://www.springframework.org/schema/mvc                            http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd">      <!-- 自动扫描该包,使SpringMVC认为包下用了@controller注解的类是控制器 -->      <context:component-scan base-package="com.ssm.web.controller" />      <!--避免IE执行AJAX时,返回JSON出现下载文件 -->      <bean id="mappingJacksonHttpMessageConverter" class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">          <property name="supportedMediaTypes">              <list>                  <value>text/html;charset=UTF-8</value>              </list>          </property>      </bean>    <!-- 启动SpringMVC的注解功能,完成请求和注解POJO的映射 -->      <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">          <property name="messageConverters">              <list>                  <ref bean="mappingJacksonHttpMessageConverter" /> <!-- JSON转换器 -->              </list>          </property>      </bean>      <!-- 定义跳转的文件的前后缀 ,视图模式配置-->      <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">          <!-- 配置视图解析的文件前缀后缀-->          <property name="prefix" value="/WEB-INF/page/" />          <property name="suffix" value=".jsp" />      </bean>      <!-- 配置文件上传,如果没有使用文件上传可以不用配置,当然如果不配,那么配置文件中也不必引入上传组件包 -->      <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">            <!-- 默认编码 -->          <property name="defaultEncoding" value="utf-8" />            <!-- 文件大小最大值 -->          <property name="maxUploadSize" value="10485760000" />            <!-- 内存中的最大值 -->          <property name="maxInMemorySize" value="40960" />        </bean>   </beans>

spring-quartz.xml

<?xml version="1.0" encoding="UTF-8"?><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"     xmlns:task="http://www.springframework.org/schema/task"    xsi:schemaLocation="        http://www.springframework.org/schema/beans         http://www.springframework.org/schema/beans/spring-beans-4.0.xsd         http://www.springframework.org/schema/context         http://www.springframework.org/schema/context/spring-context-4.0.xsd        http://www.springframework.org/schema/task         http://www.springframework.org/schema/task/spring-task-4.0.xsd ">    <context:component-scan base-package="com.ssm.quartz.job" />    <!-- 第一种:MethodInvokingJobDetailFactoryBean -->    <!-- 这种方式在你想要调用特定 bean 的一个方法的时候很是方便 -->    <bean id="simpleJobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">        <!-- mySimpleJob 任务POJO -->        <property name="targetObject" ref="mySimpleJob" />        <!-- 执行run方法 -->        <property name="targetMethod" value="run" />      </bean>    <!-- 初始延迟1秒,每20秒运行一次 -->    <bean id="simpleTrigger"  class="org.springframework.scheduling.quartz.SimpleTriggerFactoryBean">          <property name="jobDetail" ref="simpleJobDetail" />          <property name="startDelay" value="1000" />          <property name="repeatInterval" value="20000" />      </bean>    <!-- 第二种:JobDetailFactoryBean -->    <!-- 如果你需要更高级的设置,需要给作业传递数据,想更加灵活的话就使用这种方式。 -->    <bean name="firstComplexJobDetail" class="org.springframework.scheduling.quartz.JobDetailFactoryBean">          <property name="jobClass" value="com.ssm.quartz.job.FirstScheduledJob" />              <property name="jobDataMap">                  <map>                      <entry key="anotherBean" value-ref="anotherBean" />                  </map>              </property>          <property name="durability" value="true" />      </bean>     <!-- 每30秒运行一次 -->    <bean id="cronTrigger"  class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">          <property name="jobDetail" ref="firstComplexJobDetail" />          <!--<property name="cronExpression" value="0/5 * * ? * SAT-SUN" />-->          <property name="cronExpression" value="0/30 * * ? * *" />           </bean>    <bean name="secondComplexJobDetail"    class="org.springframework.scheduling.quartz.JobDetailFactoryBean">          <property name="jobClass" value="com.ssm.quartz.job.SecondScheduledJob" />          <property name="durability" value="true" />      </bean>    <!-- 总是在18:19日常运行 -->    <bean id="secondCronTrigger"  class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">          <property name="jobDetail" ref="secondComplexJobDetail" />          <property name="cronExpression" value="0 19 18 * * ? *" />      </bean>     <!-- 调度器工厂bean jobDetails粘合在一起并触发配置Quartz调度器 -->    <bean  class="org.springframework.scheduling.quartz.SchedulerFactoryBean">          <property name="jobDetails">              <list>                  <ref bean="simpleJobDetail" />                  <ref bean="firstComplexJobDetail" />                  <ref bean="secondComplexJobDetail" />              </list>          </property>          <property name="triggers">              <list>                  <ref bean="simpleTrigger" />                  <ref bean="cronTrigger" />                  <ref bean="secondCronTrigger" />              </list>          </property>      </bean></beans>        

spring-active.xml

<?xml version="1.0" encoding="UTF-8"?>  <beans xmlns="http://www.springframework.org/schema/beans"      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"     xmlns:amq="http://activemq.apache.org/schema/core"      xsi:schemaLocation="http://www.springframework.org/schema/beans                         http://www.springframework.org/schema/beans/spring-beans.xsd                          http://activemq.apache.org/schema/core                         http://activemq.apache.org/schema/core/activemq-core-5.8.0.xsd">      <!-- 真正可以产生Connection的ConnectionFactory,由对应的 JMS服务厂商提供 -->      <bean id="targetConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">          <property name="brokerURL" value="tcp://127.0.0.1:61616" />         <!-- 将该值开启官方说法是可以取得更高的发送速度(5倍)。 -->         <property name="useAsyncSend" value="true" />        <!-- 对于一个connection如果只有一个session,该值有效,否则该值无效,默认这个参数的值为true。 -->          <property name="alwaysSessionAsync" value="true" />          <property name="useDedicatedTaskRunner" value="true" />      </bean>    <!-- 发送消息的目的地(一个队列) -->      <bean id="destination" class="org.apache.activemq.command.ActiveMQQueue">          <!-- 设置消息队列的名字 -->         <constructor-arg value="dongyangyang--3?consumer.prefetchSize=100" />          <!-- consumer.prefetchSize则代表我们在此使用“消费者”预分配协议,在消费者内在足够时可以使这个值更大以获得更好的吞吐性能。 -->     </bean>      <!-- 申明对于destination这个队列的重发机制为间隔100毫秒重发一次。 -->    <amq:redeliveryPolicy id="activeMQRedeliveryPolicy" destination="#destination"                           redeliveryDelay="100" maximumRedeliveries="1" />     <!-- 应答模式队列 -->      <bean id="destination-request" class="org.apache.activemq.command.ActiveMQQueue">          <constructor-arg value="dongyangyang--4?consumer.prefetchSize=100" />      </bean>      <bean id="destination-response" class="org.apache.activemq.command.ActiveMQQueue">          <constructor-arg value="dongyangyang--4--reply" />      </bean></beans>  

log4j.properties

#定义LOG输出级别  log4j.rootLogger=INFO,Console,File#定义日志输出目的地为控制台  log4j.appender.Console=org.apache.log4j.ConsoleAppenderlog4j.appender.Console.Target=System.out#可以灵活地指定日志输出格式,下面一行是指定具体的格式  log4j.appender.Console.layout = org.apache.log4j.PatternLayoutlog4j.appender.Console.layout.ConversionPattern=[%c] - %m%n#文件大小到达指定尺寸的时候产生一个新的文件  log4j.appender.File = org.apache.log4j.RollingFileAppender#指定输出目录  log4j.appender.File.File = logs/ssm.log#定义文件最大大小  log4j.appender.File.MaxFileSize = 10MB# 输出所以日志,如果换成DEBUG表示输出DEBUG以上级别日志  log4j.appender.File.Threshold = ALLlog4j.appender.File.layout = org.apache.log4j.PatternLayoutlog4j.appender.File.layout.ConversionPattern =[%p] [%d{yyyy-MM-dd HH\:mm\:ss}][%c]%m%n

jdbc.properties

driver=com.mysql.jdbc.Driverurl=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNullusername=rootpassword=root#定义初始连接数  initialSize=10#定义最大连接数  maxActive=20#定义最大空闲  maxIdle=20#定义最小空闲  minIdle=1#定义最长等待时间  maxWait=60000

spring整合redis

spring-redis.xml

<?xml version="1.0" encoding="UTF-8"?><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"     xmlns:task="http://www.springframework.org/schema/task"    xsi:schemaLocation="        http://www.springframework.org/schema/beans         http://www.springframework.org/schema/beans/spring-beans-4.0.xsd         http://www.springframework.org/schema/context         http://www.springframework.org/schema/context/spring-context-4.0.xsd        http://www.springframework.org/schema/task         http://www.springframework.org/schema/task/spring-task-4.0.xsd ">    <!-- redis单机连接方案 -->    <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">        <property name="maxIdle" value="${maxIdle}" /> <!-- 最大能够保持idel状态的对象数  -->        <property name="maxTotal" value="${maxTotal}" /> <!-- 最大分配的对象数 -->        <property name="testOnBorrow" value="${testOnBorrow}" /> <!-- 当调用borrow Object方法时,是否进行有效性检查 -->    </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" />    </bean>    <!-- redis集群连接方案 -->    <!-- <bean name="genericObjectPoolConfig" class="org.apache.commons.pool2.impl.GenericObjectPoolConfig">          <property name="maxWaitMillis" value="${cluster.maxWaitMillis}" />          <property name="maxTotal" value="${cluster.maxTotal}" />          <property name="minIdle" value="${cluster.minIdle}" />          <property name="maxIdle" value="${cluster.maxIdle}" />      </bean> -->    <!-- <bean id="jedisCluster" class="com.ssm.common.redis.JedisClusterFactory">          <property name="connectionTimeout" value="${cluster.connectionTimeout}" />          <property name="soTimeout" value="${cluster.soTimeout}" />          <property name="maxRedirections" value="${cluster.maxRedirections}" />          <property name="genericObjectPoolConfig" ref="genericObjectPoolConfig" />          <property name="jedisClusterNodes">              <set>                  <value>${cluster.address1}</value>                  <value>${cluster.address2}</value>                 <value>${cluster.address3}</value>             </set>          </property>      </bean> -->    <!-- 真正的redis操作类,具体连接方式由jedisClient的ref属性决定 可选项为jedisClusterClient、jedisClient -->    <bean name="redisOperate" class="com.ssm.common.redis.RedisOperate">          <property name="jedisClient" ref="jedisClient" />      </bean></beans>        

redis.properties

###redis单机连接配置----start#最大能够保持idel状态的对象数maxIdle=300#最大分配的对象数maxTotal=60000#当调用borrow Object方法时,是否进行有效性检查testOnBorrow=false#redis单机连接IPredis.host=127.0.0.1#redis单机连接端口redis.port=6379###redis单机连接配置----end###redis集群连接配置----start#获取连接时的最大等待毫秒数(如果设置为阻塞时BlockWhenExhausted),如果超时就抛异常.小于零:阻塞不确定的时间,默认-1cluster.clmaxWaitMillis=-1#最大连接数,默认8个cluster.maxTotal=8#最小空闲连接数,默认0个cluster.minIdle=0#最大空闲连接数,默认8个cluster.maxIdle=8#连接超时时间cluster.connectionTimeout=3000#相应超时时间cluster.soTimeout=3000#最大重定向时间cluster.maxRedirections=5#redis集群地址cluster.address1=127.0.0.1:6379cluster.address2=127.0.0.1:6380cluster.address3=127.0.0.1:6381###redis集群连接配置----end
策略生成操作redis的客户端服务
package com.ssm.common.redis;import java.util.List;import java.util.Map;import java.util.Set;import redis.clients.jedis.Pipeline;public interface IJedisClient {    /**     * 获取缓存     * @param key 键     * @return 值     */    String get(String key);    /**     * 获取缓存     * @param key 键     * @return 值     */    Object getObject(String key);    /**     * 设置缓存     * @param key 键     * @param value 值     * @param cacheSeconds 超时时间,0为不超时     * @return     */    String set(String key, String value, int cacheSeconds);    /**     * 设置缓存     * @param key 键     * @param value 值     * @param cacheSeconds 超时时间,0为不超时     * @return     */    String setObject(String key, Object value, int cacheSeconds);    /**     * 获取List缓存     * @param key 键     * @return 值     */    List<String> getList(String key);    /**     * 获取List缓存     * @param key 键     * @return 值     */    List<Object> getObjectList(String key);    /**     * 设置List缓存     * @param key 键     * @param value 值     * @param cacheSeconds 超时时间,0为不超时     * @return     */    long setList(String key, List<String> value, int cacheSeconds);    /**     * 设置List缓存     * @param key 键     * @param value 值     * @param cacheSeconds 超时时间,0为不超时     * @return     */    long setObjectList(String key, List<Object> value, int cacheSeconds);    /**     * 向List缓存中添加值     * @param key 键     * @param value 值     * @return     */    long listAdd(String key, String... value);    /**     * 向List缓存中添加值     * @param key 键     * @param value 值     * @return     */    long listObjectAdd(String key, Object... value);    /**     * 获取缓存     * @param key 键     * @return 值     */    Set<String> getSet(String key);    /**     * 获取缓存     * @param key 键     * @return 值     */    Set<Object> getObjectSet(String key);    /**     * 设置Set缓存     * @param key 键     * @param value 值     * @param cacheSeconds 超时时间,0为不超时     * @return     */    long setSet(String key, Set<String> value, int cacheSeconds);    /**     * 设置Set缓存     * @param key 键     * @param value 值     * @param cacheSeconds 超时时间,0为不超时     * @return     */    long setObjectSet(String key, Set<Object> value, int cacheSeconds);    /**     * 向Set缓存中添加值     * @param key 键     * @param value 值     * @return     */    long setSetAdd(String key, String... value);    /**     * 向Set缓存中添加值     * @param key 键     * @param value 值     * @return     */    long setSetObjectAdd(String key, Object... value);    /**     * 获取Map缓存     * @param key 键     * @return 值     */    Map<String, String> getMap(String key);    /**     * 获取Map缓存     * @param key 键     * @return 值     */    Map<String, Object> getObjectMap(String key);    /**     * 设置Map缓存     * @param key 键     * @param value 值     * @param cacheSeconds 超时时间,0为不超时     * @return     */    String setMap(String key, Map<String, String> value, int cacheSeconds);    /**     * 设置Map缓存     * @param key 键     * @param value 值     * @param cacheSeconds 超时时间,0为不超时     * @return     */    String setObjectMap(String key, Map<String, Object> value,int cacheSeconds);    /**     * 向Map缓存中添加值     * @param key 键     * @param value 值     * @return     */    String mapPut(String key, Map<String, String> value);    /**     * 向Map缓存中添加值     * @param key 键     * @param value 值     * @return     */    String mapObjectPut(String key, Map<String, Object> value);    /**     * 移除Map缓存中的值     * @param key 键     * @param value 值     * @return     */    long mapRemove(String key, String mapKey);    /**     * 移除Map缓存中的值     * @param key 键     * @param value 值     * @return     */    long mapObjectRemove(String key, String mapKey);    /**     * 判断Map缓存中的Key是否存在     * @param key 键     * @param value 值     * @return     */    boolean mapExists(String key, String mapKey);    /**     * 判断Map缓存中的Key是否存在     * @param key 键     * @param value 值     * @return     */    boolean mapObjectExists(String key, String mapKey);    /**     * 删除缓存     * @param key 键     * @return     */    long del(String key);    /**     * 删除缓存     * @param key 键     * @return     */    long delObject(String key);    /**     * 缓存是否存在     * @param key 键     * @return     */    boolean exists(String key);    /**     * 缓存是否存在     * @param key 键     * @return     */    boolean existsObject(String key);    /**     * 模拟分布式锁     * @autho 董杨炀     * @time 2017年5月6日 上午10:24:44     * @param key     * @param value     * @return     */    long setnx(String key,String value);    /**     * 为给定  key  设置生存时间,当  key  过期时(生存时间为  0  ),它会被自动删除。     * @autho 董杨炀     * @time 2017年5月6日 上午10:40:23     * @param key     * @param ttl     */    void expire(String key, int ttl);    /**     * 批量解锁     * @autho 董杨炀     * @time 2017年5月6日 上午11:03:35     * @param array     */    void del(String[] array);    /**     * 获取redis批量处理得对象     * @autho 董杨炀     * @time 2017年5月6日 上午11:08:58     * @return     */    Pipeline pipelined();}
package com.ssm.common.redis;import java.util.List;import java.util.Map;import java.util.Set;import javax.annotation.Resource;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.stereotype.Service;import com.google.common.collect.Lists;import com.google.common.collect.Maps;import com.google.common.collect.Sets;import com.ssm.utils.SerializeUtil;import com.ssm.utils.StringUtils;import redis.clients.jedis.Jedis;import redis.clients.jedis.JedisPool;import redis.clients.jedis.Pipeline;import redis.clients.jedis.exceptions.JedisException;/** * 单机方式redis客户端操作 * @author 353654 * */@Service("jedisClient")public class JedisClient implements IJedisClient {    private static Logger logger = LoggerFactory.getLogger(JedisClient.class);    @Resource    private JedisPool jedisPool;    /**     * 获取缓存     * @autho 董杨炀     * @time 2017年5月6日 上午11:16:19     * @param key     * @return     */    public  String get(String 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;    }    /**     * 获取缓存     * @autho 董杨炀     * @time 2017年5月6日 上午11:16:15     * @param key     * @return     */    public  Object getObject(String key) {        Object value = null;        Jedis jedis = null;        try {            jedis = getResource();            if (jedis.exists(getBytesKey(key))) {                value = toObject(jedis.get(getBytesKey(key)));                logger.debug("getObject {} = {}", key, value);            }        } catch (Exception e) {            logger.warn("getObject {} = {}", key, value, e);        } finally {            returnResource(jedis);        }        return value;    }    /**     * 设置缓存     * @autho 董杨炀     * @time 2017年5月6日 上午11:16:10     * @param key     * @param value     * @param cacheSeconds     * @return     */    public  String set(String key, String value, int cacheSeconds) {        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;    }    /**     * 设置缓存     * @autho 董杨炀     * @time 2017年5月6日 上午11:16:03     * @param key     * @param value     * @param cacheSeconds     * @return     */    public  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, value, e);        } finally {            returnResource(jedis);        }        return result;    }    /**     * 获取List缓存     * @autho 董杨炀     * @time 2017年5月6日 上午11:15:57     * @param key     * @return     */    public  List<String> getList(String key) {        List<String> value = null;        Jedis jedis = null;        try {            jedis = getResource();            if (jedis.exists(key)) {                value = jedis.lrange(key, 0, -1);                logger.debug("getList {} = {}", key, value);            }        } catch (Exception e) {            logger.warn("getList {} = {}", key, value, e);        } finally {            returnResource(jedis);        }        return value;    }    /**     * 获取List缓存     * @autho 董杨炀     * @time 2017年5月6日 上午11:15:52     * @param key     * @return     */    public  List<Object> getObjectList(String key) {        List<Object> value = null;        Jedis jedis = null;        try {            jedis = getResource();            if (jedis.exists(getBytesKey(key))) {                List<byte[]> list = jedis.lrange(getBytesKey(key), 0, -1);                value = Lists.newArrayList();                for (byte[] bs : list){                    value.add(toObject(bs));                }                logger.debug("getObjectList {} = {}", key, value);            }        } catch (Exception e) {            logger.warn("getObjectList {} = {}", key, value, e);        } finally {            returnResource(jedis);        }        return value;    }    /**     * 设置List缓存     * @autho 董杨炀     * @time 2017年5月6日 上午11:15:47     * @param key     * @param value     * @param cacheSeconds     * @return     */    public  long setList(String key, List<String> value, int cacheSeconds) {        long result = 0;        Jedis jedis = null;        try {            jedis = getResource();            if (jedis.exists(key)) {                jedis.del(key);            }            result = jedis.rpush(key, (String[])value.toArray());            if (cacheSeconds != 0) {                jedis.expire(key, cacheSeconds);            }            logger.debug("setList {} = {}", key, value);        } catch (Exception e) {            logger.warn("setList {} = {}", key, value, e);        } finally {            returnResource(jedis);        }        return result;    }    /**     * 设置List缓存     * @autho 董杨炀     * @time 2017年5月6日 上午11:15:41     * @param key     * @param value     * @param cacheSeconds     * @return     */    public  long setObjectList(String key, List<Object> value, int cacheSeconds) {        long result = 0;        Jedis jedis = null;        try {            jedis = getResource();            if (jedis.exists(getBytesKey(key))) {                jedis.del(key);            }            List<byte[]> list = Lists.newArrayList();            for (Object o : value){                list.add(toBytes(o));            }            result = jedis.rpush(getBytesKey(key), (byte[][])list.toArray());            if (cacheSeconds != 0) {                jedis.expire(key, cacheSeconds);            }            logger.debug("setObjectList {} = {}", key, value);        } catch (Exception e) {            logger.warn("setObjectList {} = {}", key, value, e);        } finally {            returnResource(jedis);        }        return result;    }    /**     * 向List缓存中添加值     * @autho 董杨炀     * @time 2017年5月6日 上午11:15:35     * @param key     * @param value     * @return     */    public  long listAdd(String key, String... value) {        long result = 0;        Jedis jedis = null;        try {            jedis = getResource();            result = jedis.rpush(key, value);            logger.debug("listAdd {} = {}", key, value);        } catch (Exception e) {            logger.warn("listAdd {} = {}", key, value, e);        } finally {            returnResource(jedis);        }        return result;    }    /**     * 向List缓存中添加值     * @autho 董杨炀     * @time 2017年5月6日 上午11:15:29     * @param key     * @param value     * @return     */    public  long listObjectAdd(String key, Object... value) {        long result = 0;        Jedis jedis = null;        try {            jedis = getResource();            List<byte[]> list = Lists.newArrayList();            for (Object o : value){                list.add(toBytes(o));            }            result = jedis.rpush(getBytesKey(key), (byte[][])list.toArray());            logger.debug("listObjectAdd {} = {}", key, value);        } catch (Exception e) {            logger.warn("listObjectAdd {} = {}", key, value, e);        } finally {            returnResource(jedis);        }        return result;    }    /**     * 获取缓存     * @autho 董杨炀     * @time 2017年5月6日 上午11:15:24     * @param key     * @return     */    public  Set<String> getSet(String key) {        Set<String> value = null;        Jedis jedis = null;        try {            jedis = getResource();            if (jedis.exists(key)) {                value = jedis.smembers(key);                logger.debug("getSet {} = {}", key, value);            }        } catch (Exception e) {            logger.warn("getSet {} = {}", key, value, e);        } finally {            returnResource(jedis);        }        return value;    }    /**     * 获取缓存     * @autho 董杨炀     * @time 2017年5月6日 上午11:15:18     * @param key     * @return     */    public  Set<Object> getObjectSet(String key) {        Set<Object> value = null;        Jedis jedis = null;        try {            jedis = getResource();            if (jedis.exists(getBytesKey(key))) {                value = Sets.newHashSet();                Set<byte[]> set = jedis.smembers(getBytesKey(key));                for (byte[] bs : set){                    value.add(toObject(bs));                }                logger.debug("getObjectSet {} = {}", key, value);            }        } catch (Exception e) {            logger.warn("getObjectSet {} = {}", key, value, e);        } finally {            returnResource(jedis);        }        return value;    }    /**     * 设置Set缓存     * @autho 董杨炀     * @time 2017年5月6日 上午11:15:12     * @param key     * @param value     * @param cacheSeconds     * @return     */    public  long setSet(String key, Set<String> value, int cacheSeconds) {        long result = 0;        Jedis jedis = null;        try {            jedis = getResource();            if (jedis.exists(key)) {                jedis.del(key);            }            result = jedis.sadd(key, (String[])value.toArray());            if (cacheSeconds != 0) {                jedis.expire(key, cacheSeconds);            }            logger.debug("setSet {} = {}", key, value);        } catch (Exception e) {            logger.warn("setSet {} = {}", key, value, e);        } finally {            returnResource(jedis);        }        return result;    }    /**     * 设置Set缓存     * @autho 董杨炀     * @time 2017年5月6日 上午11:15:07     * @param key     * @param value     * @param cacheSeconds     * @return     */    public  long setObjectSet(String key, Set<Object> value, int cacheSeconds) {        long result = 0;        Jedis jedis = null;        try {            jedis = getResource();            if (jedis.exists(getBytesKey(key))) {                jedis.del(key);            }            Set<byte[]> set = Sets.newHashSet();            for (Object o : value){                set.add(toBytes(o));            }            result = jedis.sadd(getBytesKey(key), (byte[][])set.toArray());            if (cacheSeconds != 0) {                jedis.expire(key, cacheSeconds);            }            logger.debug("setObjectSet {} = {}", key, value);        } catch (Exception e) {            logger.warn("setObjectSet {} = {}", key, value, e);        } finally {            returnResource(jedis);        }        return result;    }    /**     * 向Set缓存中添加值     * @autho 董杨炀     * @time 2017年5月6日 上午11:15:02     * @param key     * @param value     * @return     */    public  long setSetAdd(String key, String... value) {        long result = 0;        Jedis jedis = null;        try {            jedis = getResource();            result = jedis.sadd(key, value);            logger.debug("setSetAdd {} = {}", key, value);        } catch (Exception e) {            logger.warn("setSetAdd {} = {}", key, value, e);        } finally {            returnResource(jedis);        }        return result;    }    /**     * 向Set缓存中添加值     * @autho 董杨炀     * @time 2017年5月6日 上午11:14:57     * @param key     * @param value     * @return     */    public  long setSetObjectAdd(String key, Object... value) {        long result = 0;        Jedis jedis = null;        try {            jedis = getResource();            Set<byte[]> set = Sets.newHashSet();            for (Object o : value){                set.add(toBytes(o));            }            result = jedis.rpush(getBytesKey(key), (byte[][])set.toArray());            logger.debug("setSetObjectAdd {} = {}", key, value);        } catch (Exception e) {            logger.warn("setSetObjectAdd {} = {}", key, value, e);        } finally {            returnResource(jedis);        }        return result;    }    /**     * 获取Map缓存     * @autho 董杨炀     * @time 2017年5月6日 上午11:14:46     * @param key     * @return     */    public  Map<String, String> getMap(String key) {        Map<String, String> value = null;        Jedis jedis = null;        try {            jedis = getResource();            if (jedis.exists(key)) {                value = jedis.hgetAll(key);                logger.debug("getMap {} = {}", key, value);            }        } catch (Exception e) {            logger.warn("getMap {} = {}", key, value, e);        } finally {            returnResource(jedis);        }        return value;    }    /**     * 获取Map缓存     * @autho 董杨炀     * @time 2017年5月6日 上午11:14:41     * @param key     * @return     */    public  Map<String, Object> getObjectMap(String key) {        Map<String, Object> value = null;        Jedis jedis = null;        try {            jedis = getResource();            if (jedis.exists(getBytesKey(key))) {                value = Maps.newHashMap();                Map<byte[], byte[]> map = jedis.hgetAll(getBytesKey(key));                for (Map.Entry<byte[], byte[]> e : map.entrySet()){                    value.put(new String(e.getKey()), toObject(e.getValue()));                }                logger.debug("getObjectMap {} = {}", key, value);            }        } catch (Exception e) {            logger.warn("getObjectMap {} = {}", key, value, e);        } finally {            returnResource(jedis);        }        return value;    }    /**     * 设置Map缓存     * @autho 董杨炀     * @time 2017年5月6日 上午11:14:36     * @param key     * @param value     * @param cacheSeconds     * @return     */    public  String setMap(String key, Map<String, String> value, int cacheSeconds) {        String result = null;        Jedis jedis = null;        try {            jedis = getResource();            if (jedis.exists(key)) {                jedis.del(key);            }            result = jedis.hmset(key, value);            if (cacheSeconds != 0) {                jedis.expire(key, cacheSeconds);            }            logger.debug("setMap {} = {}", key, value);        } catch (Exception e) {            logger.warn("setMap {} = {}", key, value, e);        } finally {            returnResource(jedis);        }        return result;    }    /**     * 设置Map缓存     * @autho 董杨炀     * @time 2017年5月6日 上午11:14:29     * @param key     * @param value     * @param cacheSeconds     * @return     */    public  String setObjectMap(String key, Map<String, Object> value, int cacheSeconds) {        String result = null;        Jedis jedis = null;        try {            jedis = getResource();            if (jedis.exists(getBytesKey(key))) {                jedis.del(key);            }            Map<byte[], byte[]> map = Maps.newHashMap();            for (Map.Entry<String, Object> e : value.entrySet()){                map.put(getBytesKey(e.getKey()), toBytes(e.getValue()));            }            result = jedis.hmset(getBytesKey(key), (Map<byte[], byte[]>)map);            if (cacheSeconds != 0) {                jedis.expire(key, cacheSeconds);            }            logger.debug("setObjectMap {} = {}", key, value);        } catch (Exception e) {            logger.warn("setObjectMap {} = {}", key, value, e);        } finally {            returnResource(jedis);        }        return result;    }    /**     * 向Map缓存中添加值     * @autho 董杨炀     * @time 2017年5月6日 上午11:14:24     * @param key     * @param value     * @return     */    public  String mapPut(String key, Map<String, String> value) {        String result = null;        Jedis jedis = null;        try {            jedis = getResource();            result = jedis.hmset(key, value);            logger.debug("mapPut {} = {}", key, value);        } catch (Exception e) {            logger.warn("mapPut {} = {}", key, value, e);        } finally {            returnResource(jedis);        }        return result;    }    /**     * 向Map缓存中添加值     * @autho 董杨炀     * @time 2017年5月6日 上午11:14:19     * @param key     * @param value     * @return     */    public  String mapObjectPut(String key, Map<String, Object> value) {        String result = null;        Jedis jedis = null;        try {            jedis = getResource();            Map<byte[], byte[]> map = Maps.newHashMap();            for (Map.Entry<String, Object> e : value.entrySet()){                map.put(getBytesKey(e.getKey()), toBytes(e.getValue()));            }            result = jedis.hmset(getBytesKey(key), (Map<byte[], byte[]>)map);            logger.debug("mapObjectPut {} = {}", key, value);        } catch (Exception e) {            logger.warn("mapObjectPut {} = {}", key, value, e);        } finally {            returnResource(jedis);        }        return result;    }    /**     * 移除Map缓存中的值     * @autho 董杨炀     * @time 2017年5月6日 上午11:14:11     * @param key     * @param mapKey     * @return     */    public  long mapRemove(String key, String mapKey) {        long result = 0;        Jedis jedis = null;        try {            jedis = getResource();            result = jedis.hdel(key, mapKey);            logger.debug("mapRemove {}  {}", key, mapKey);        } catch (Exception e) {            logger.warn("mapRemove {}  {}", key, mapKey, e);        } finally {            returnResource(jedis);        }        return result;    }    /**     * 移除Map缓存中的值     * @autho 董杨炀     * @time 2017年5月6日 上午11:14:04     * @param key     * @param mapKey     * @return     */    public  long mapObjectRemove(String key, String mapKey) {        long result = 0;        Jedis jedis = null;        try {            jedis = getResource();            result = jedis.hdel(getBytesKey(key), getBytesKey(mapKey));            logger.debug("mapObjectRemove {}  {}", key, mapKey);        } catch (Exception e) {            logger.warn("mapObjectRemove {}  {}", key, mapKey, e);        } finally {            returnResource(jedis);        }        return result;    }    /**     * 判断Map缓存中的Key是否存在     * @autho 董杨炀     * @time 2017年5月6日 上午11:13:58     * @param key     * @param mapKey     * @return     */    public  boolean mapExists(String key, String mapKey) {        boolean result = false;        Jedis jedis = null;        try {            jedis = getResource();            result = jedis.hexists(key, mapKey);            logger.debug("mapExists {}  {}", key, mapKey);        } catch (Exception e) {            logger.warn("mapExists {}  {}", key, mapKey, e);        } finally {            returnResource(jedis);        }        return result;    }    /**     * 判断Map缓存中的Key是否存在     * @autho 董杨炀     * @time 2017年5月6日 上午11:13:52     * @param key     * @param mapKey     * @return     */    public  boolean mapObjectExists(String key, String mapKey) {        boolean result = false;        Jedis jedis = null;        try {            jedis = getResource();            result = jedis.hexists(getBytesKey(key), getBytesKey(mapKey));            logger.debug("mapObjectExists {}  {}", key, mapKey);        } catch (Exception e) {            logger.warn("mapObjectExists {}  {}", key, mapKey, e);        } finally {            returnResource(jedis);        }        return result;    }    /**     * 删除缓存     * @autho 董杨炀     * @time 2017年5月6日 上午11:13:47     * @param key     * @return     */    public  long del(String key) {        long result = 0;        Jedis jedis = null;        try {            jedis = getResource();            if (jedis.exists(key)){                result = jedis.del(key);                logger.debug("del {}", key);            }else{                logger.debug("del {} not exists", key);            }        } catch (Exception e) {            logger.warn("del {}", key, e);        } finally {            returnResource(jedis);        }        return result;    }    /**     * 删除缓存     * @autho 董杨炀     * @time 2017年5月6日 上午11:13:42     * @param key     * @return     */    public  long delObject(String key) {        long result = 0;        Jedis jedis = null;        try {            jedis = getResource();            if (jedis.exists(getBytesKey(key))){                result = jedis.del(getBytesKey(key));                logger.debug("delObject {}", key);            }else{                logger.debug("delObject {} not exists", key);            }        } catch (Exception e) {            logger.warn("delObject {}", key, e);        } finally {            returnResource(jedis);        }        return result;    }    /**     * 缓存是否存在     * @autho 董杨炀     * @time 2017年5月6日 上午11:13:37     * @param key     * @return     */    public  boolean exists(String key) {        boolean result = false;        Jedis jedis = null;        try {            jedis = getResource();            result = jedis.exists(key);            logger.debug("exists {}", key);        } catch (Exception e) {            logger.warn("exists {}", key, e);        } finally {            returnResource(jedis);        }        return result;    }    /**     * 缓存是否存在     * @autho 董杨炀     * @time 2017年5月6日 上午11:13:27     * @param key     * @return     */    public  boolean existsObject(String key) {        boolean result = false;        Jedis jedis = null;        try {            jedis = getResource();            result = jedis.exists(getBytesKey(key));            logger.debug("existsObject {}", key);        } catch (Exception e) {            logger.warn("existsObject {}", key, e);        } finally {            returnResource(jedis);        }        return result;    }    /**     * 获取资源     * @autho 董杨炀     * @time 2017年5月6日 上午11:13:19     * @return     * @throws JedisException     */    public  Jedis getResource() throws JedisException {        Jedis jedis = null;        try {            jedis = jedisPool.getResource();//          logger.debug("getResource.", jedis);        } catch (JedisException e) {            logger.warn("getResource.", e);            returnBrokenResource(jedis);            throw e;        }        return jedis;    }    /**     * 归还资源     * @autho 董杨炀     * @time 2017年5月6日 上午11:13:13     * @param jedis     */    @SuppressWarnings("deprecation")    public  void returnBrokenResource(Jedis jedis) {        if (jedis != null) {            jedisPool.returnBrokenResource(jedis);        }    }    /**     * 释放资源     * @autho 董杨炀     * @time 2017年5月6日 上午11:13:06     * @param jedis     */    @SuppressWarnings("deprecation")    public  void returnResource(Jedis jedis) {        if (jedis != null) {            jedisPool.returnResource(jedis);        }    }    /**     * 获取byte[]类型Key     * @autho 董杨炀     * @time 2017年5月6日 上午11:13:01     * @param object     * @return     */    public static byte[] getBytesKey(Object object){        if(object instanceof String){            return StringUtils.getBytes((String)object);        }else{            return SerializeUtil.serialize(object);        }    }    /**     * Object转换byte[]类型     * @autho 董杨炀     * @time 2017年5月6日 上午11:12:55     * @param object     * @return     */    public static byte[] toBytes(Object object){        return SerializeUtil.serialize(object);    }    /**     * byte[]型转换Object     * @param key     * @return     */    public static Object toObject(byte[] bytes){        return SerializeUtil.deserialize(bytes);    }    /**     * @autho 董杨炀     * @time 2017年5月6日 上午10:25:16     * @param key     * @param value     * @return     */    @Override    public long setnx(String key, String value) {        return this.getResource().setnx(key,value);    }    /**     *      * @autho 董杨炀     * @time 2017年5月6日 上午11:03:52     * @param key     * @param ttl     */    @Override    public void expire(String key, int ttl) {        this.getResource().expire(key,ttl);    }    /**     * @autho 董杨炀     * @time 2017年5月6日 上午11:03:52     * @param array     */    @Override    public void del(String[] array) {        this.getResource().del(array);    }    /**     * @autho 董杨炀     * @time 2017年5月6日 上午11:09:28     * @return     */    @Override    public Pipeline pipelined() {        return this.getResource().pipelined();    }}
package com.ssm.common.redis;import java.util.List;import java.util.Map;import java.util.Set;import javax.annotation.Resource;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.beans.factory.annotation.Autowired;import com.google.common.collect.Lists;import com.google.common.collect.Maps;import com.google.common.collect.Sets;import com.ssm.utils.SerializeUtil;import com.ssm.utils.StringUtils;import redis.clients.jedis.JedisCluster;import redis.clients.jedis.Pipeline;/** * 集群方式redis客户端操作 * @author 353654 * *///集群环境才开启Service,在spring注入//@Service("jedisClusterClient")public class JedisClusterClient implements IJedisClient{    private static Logger logger = LoggerFactory.getLogger(JedisClusterClient.class);    @Resource    private JedisCluster jedisCluster;    @Override    public  String get(String key) {        String value = null;        try {            if (jedisCluster.exists(key)) {                value = jedisCluster.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;    }    @Override    public   Object getObject(String key) {        Object value = null;        try {            if (jedisCluster.exists(getBytesKey(key))) {                value = toObject(jedisCluster.get(getBytesKey(key)));                logger.debug("getObject {} = {}", key, value);            }        } catch (Exception e) {            logger.warn("getObject {} = {}", key, value, e);        } finally {            //returnResource(jedis);//          try {//              jedisCluster.close();//          } catch (IOException e) {//              e.printStackTrace();//          }        }        return value;    }    @Override    public   String set(String key, String value, int cacheSeconds) {        String result = null;        try {            result = jedisCluster.set(key, value);            if (cacheSeconds != 0) {                jedisCluster.expire(key, cacheSeconds);            }            logger.debug("set {} = {}", key, value);        } catch (Exception e) {            logger.warn("set {} = {}", key, value, e);        } finally {            //returnResource(jedis);        }        return result;    }    @Override    public   String setObject(String key, Object value, int cacheSeconds) {        String result = null;        try {            result = jedisCluster.set(getBytesKey(key), toBytes(value));            if (cacheSeconds != 0) {                jedisCluster.expire(key, cacheSeconds);            }            logger.debug("setObject {} = {}", key, value);        } catch (Exception e) {            logger.warn("setObject {} = {}", key, value, e);        } finally {            //returnResource(jedis);        }        return result;    }    @Override    public  List<String> getList(String key) {        List<String> value = null;        try {            if (jedisCluster.exists(key)) {                value = jedisCluster.lrange(key, 0, -1);                logger.debug("getList {} = {}", key, value);            }        } catch (Exception e) {            logger.warn("getList {} = {}", key, value, e);        } finally {            //returnResource(jedis);        }        return value;    }    @Override    public   List<Object> getObjectList(String key) {        List<Object> value = null;        try {            if (jedisCluster.exists(getBytesKey(key))) {                List<byte[]> list = jedisCluster.lrange(getBytesKey(key), 0, -1);                value = Lists.newArrayList();                for (byte[] bs : list){                    value.add(toObject(bs));                }                logger.debug("getObjectList {} = {}", key, value);            }        } catch (Exception e) {            logger.warn("getObjectList {} = {}", key, value, e);        } finally {            //returnResource(jedis);        }        return value;    }    @Override    public   long setList(String key, List<String> value, int cacheSeconds) {        long result = 0;        try {            if (jedisCluster.exists(key)) {                jedisCluster.del(key);            }            result = jedisCluster.rpush(key, (String[])value.toArray());            if (cacheSeconds != 0) {                jedisCluster.expire(key, cacheSeconds);            }            logger.debug("setList {} = {}", key, value);        } catch (Exception e) {            logger.warn("setList {} = {}", key, value, e);        } finally {            //returnResource(jedis);        }        return result;    }    @Override    public   long setObjectList(String key, List<Object> value, int cacheSeconds) {        long result = 0;        try {            if (jedisCluster.exists(getBytesKey(key))) {                jedisCluster.del(key);            }            List<byte[]> list = Lists.newArrayList();            for (Object o : value){                list.add(toBytes(o));            }            result = jedisCluster.rpush(getBytesKey(key), (byte[][])list.toArray());            if (cacheSeconds != 0) {                jedisCluster.expire(key, cacheSeconds);            }            logger.debug("setObjectList {} = {}", key, value);        } catch (Exception e) {            logger.warn("setObjectList {} = {}", key, value, e);        } finally {            //returnResource(jedis);        }        return result;    }    @Override    public   long listAdd(String key, String... value) {        long result = 0;        try {            result = jedisCluster.rpush(key, value);            logger.debug("listAdd {} = {}", key, value);        } catch (Exception e) {            logger.warn("listAdd {} = {}", key, value, e);        } finally {//          returnResource(jedis);        }        return result;    }    @Override    public   long listObjectAdd(String key, Object... value) {        long result = 0;        try {            List<byte[]> list = Lists.newArrayList();            for (Object o : value){                list.add(toBytes(o));            }            result = jedisCluster.rpush(getBytesKey(key), (byte[][])list.toArray());            logger.debug("listObjectAdd {} = {}", key, value);        } catch (Exception e) {            logger.warn("listObjectAdd {} = {}", key, value, e);        } finally {//          returnResource(jedis);        }        return result;    }    @Override    public   Set<String> getSet(String key) {        Set<String> value = null;        try {            if (jedisCluster.exists(key)) {                value = jedisCluster.smembers(key);                logger.debug("getSet {} = {}", key, value);            }        } catch (Exception e) {            logger.warn("getSet {} = {}", key, value, e);        } finally {//          returnResource(jedis);        }        return value;    }    @Override    public Set<Object> getObjectSet(String key) {        Set<Object> value = null;        try {            if (jedisCluster.exists(getBytesKey(key))) {                value = Sets.newHashSet();                Set<byte[]> set = jedisCluster.smembers(getBytesKey(key));                for (byte[] bs : set){                    value.add(toObject(bs));                }                logger.debug("getObjectSet {} = {}", key, value);            }        } catch (Exception e) {            logger.warn("getObjectSet {} = {}", key, value, e);        } finally {//          returnResource(jedis);        }        return value;    }    @Override    public   long setSet(String key, Set<String> value, int cacheSeconds) {        long result = 0;        try {            if (jedisCluster.exists(key)) {                jedisCluster.del(key);            }            result = jedisCluster.sadd(key, (String[])value.toArray());            if (cacheSeconds != 0) {                jedisCluster.expire(key, cacheSeconds);            }            logger.debug("setSet {} = {}", key, value);        } catch (Exception e) {            logger.warn("setSet {} = {}", key, value, e);        } finally {//          returnResource(jedis);        }        return result;    }    @Override    public   long setObjectSet(String key, Set<Object> value, int cacheSeconds) {        long result = 0;        try {            if (jedisCluster.exists(getBytesKey(key))) {                jedisCluster.del(key);            }            Set<byte[]> set = Sets.newHashSet();            for (Object o : value){                set.add(toBytes(o));            }            result = jedisCluster.sadd(getBytesKey(key), (byte[][])set.toArray());            if (cacheSeconds != 0) {                jedisCluster.expire(key, cacheSeconds);            }            logger.debug("setObjectSet {} = {}", key, value);        } catch (Exception e) {            logger.warn("setObjectSet {} = {}", key, value, e);        } finally {//          returnResource(jedis);        }        return result;    }    @Override    public   long setSetAdd(String key, String... value) {        long result = 0;        try {            result = jedisCluster.sadd(key, value);            logger.debug("setSetAdd {} = {}", key, value);        } catch (Exception e) {            logger.warn("setSetAdd {} = {}", key, value, e);        } finally {//          returnResource(jedis);        }        return result;    }    @Override    public   long setSetObjectAdd(String key, Object... value) {        long result = 0;        try {            Set<byte[]> set = Sets.newHashSet();            for (Object o : value){                set.add(toBytes(o));            }            result = jedisCluster.rpush(getBytesKey(key), (byte[][])set.toArray());            logger.debug("setSetObjectAdd {} = {}", key, value);        } catch (Exception e) {            logger.warn("setSetObjectAdd {} = {}", key, value, e);        } finally {//          returnResource(jedis);        }        return result;    }    @Override    public   Map<String, String> getMap(String key) {        Map<String, String> value = null;        try {            if (jedisCluster.exists(key)) {                value = jedisCluster.hgetAll(key);                logger.debug("getMap {} = {}", key, value);            }        } catch (Exception e) {            logger.warn("getMap {} = {}", key, value, e);        } finally {//          returnResource(jedis);        }        return value;    }    @Override    public   Map<String, Object> getObjectMap(String key) {        Map<String, Object> value = null;        try {            if (jedisCluster.exists(getBytesKey(key))) {                value = Maps.newHashMap();                Map<byte[], byte[]> map = jedisCluster.hgetAll(getBytesKey(key));                for (Map.Entry<byte[], byte[]> e : map.entrySet()){                    value.put(new String(e.getKey()), toObject(e.getValue()));                }                logger.debug("getObjectMap {} = {}", key, value);            }        } catch (Exception e) {            logger.warn("getObjectMap {} = {}", key, value, e);        } finally {        }        return value;    }    @Override    public   String setMap(String key, Map<String, String> value, int cacheSeconds) {        String result = null;        try {            if (jedisCluster.exists(key)) {                jedisCluster.del(key);            }            result = jedisCluster.hmset(key, value);            if (cacheSeconds != 0) {                jedisCluster.expire(key, cacheSeconds);            }            logger.debug("setMap {} = {}", key, value);        } catch (Exception e) {            logger.warn("setMap {} = {}", key, value, e);        } finally {//          returnResource(jedis);        }        return result;    }    @Override    public   String setObjectMap(String key, Map<String, Object> value, int cacheSeconds) {        String result = null;        try {            if (jedisCluster.exists(getBytesKey(key))) {                jedisCluster.del(key);            }            Map<byte[], byte[]> map = Maps.newHashMap();            for (Map.Entry<String, Object> e : value.entrySet()){                map.put(getBytesKey(e.getKey()), toBytes(e.getValue()));            }            result = jedisCluster.hmset(getBytesKey(key), (Map<byte[], byte[]>)map);            if (cacheSeconds != 0) {                jedisCluster.expire(key, cacheSeconds);            }            logger.debug("setObjectMap {} = {}", key, value);        } catch (Exception e) {            logger.warn("setObjectMap {} = {}", key, value, e);        } finally {//          returnResource(jedis);        }        return result;    }    @Override    public   String mapPut(String key, Map<String, String> value) {        String result = null;        try {            result = jedisCluster.hmset(key, value);            logger.debug("mapPut {} = {}", key, value);        } catch (Exception e) {            logger.warn("mapPut {} = {}", key, value, e);        } finally {//          returnResource(jedis);        }        return result;    }    @Override    public   String mapObjectPut(String key, Map<String, Object> value) {        String result = null;        try {            Map<byte[], byte[]> map = Maps.newHashMap();            for (Map.Entry<String, Object> e : value.entrySet()){                map.put(getBytesKey(e.getKey()), toBytes(e.getValue()));            }            result = jedisCluster.hmset(getBytesKey(key), (Map<byte[], byte[]>)map);            logger.debug("mapObjectPut {} = {}", key, value);        } catch (Exception e) {            logger.warn("mapObjectPut {} = {}", key, value, e);        } finally {//          returnResource(jedis);        }        return result;    }    @Override    public   long mapRemove(String key, String mapKey) {        long result = 0;        try {            result = jedisCluster.hdel(key, mapKey);            logger.debug("mapRemove {}  {}", key, mapKey);        } catch (Exception e) {            logger.warn("mapRemove {}  {}", key, mapKey, e);        } finally {//          returnResource(jedis);        }        return result;    }    @Override    public   long mapObjectRemove(String key, String mapKey) {        long result = 0;        try {            result = jedisCluster.hdel(getBytesKey(key), getBytesKey(mapKey));            logger.debug("mapObjectRemove {}  {}", key, mapKey);        } catch (Exception e) {            logger.warn("mapObjectRemove {}  {}", key, mapKey, e);        } finally {//          returnResource(jedis);        }        return result;    }    @Override    public   boolean mapExists(String key, String mapKey) {        boolean result = false;        try {            result = jedisCluster.hexists(key, mapKey);            logger.debug("mapExists {}  {}", key, mapKey);        } catch (Exception e) {            logger.warn("mapExists {}  {}", key, mapKey, e);        } finally {//          returnResource(jedis);        }        return result;    }    @Override    public   boolean mapObjectExists(String key, String mapKey) {        boolean result = false;        try {            result = jedisCluster.hexists(getBytesKey(key), getBytesKey(mapKey));            logger.debug("mapObjectExists {}  {}", key, mapKey);        } catch (Exception e) {            logger.warn("mapObjectExists {}  {}", key, mapKey, e);        } finally {//          returnResource(jedis);        }        return result;    }    @Override    public   long del(String key) {        long result = 0;        try {            if (jedisCluster.exists(key)){                result = jedisCluster.del(key);                logger.debug("del {}", key);            }else{                logger.debug("del {} not exists", key);            }        } catch (Exception e) {            logger.warn("del {}", key, e);        } finally {//          returnResource(jedis);        }        return result;    }    @Override    public   long delObject(String key) {        long result = 0;        try {            if (jedisCluster.exists(getBytesKey(key))){                result = jedisCluster.del(getBytesKey(key));                logger.debug("delObject {}", key);            }else{                logger.debug("delObject {} not exists", key);            }        } catch (Exception e) {            logger.warn("delObject {}", key, e);        } finally {//          returnResource(jedis);        }        return result;    }    @Override    public   boolean exists(String key) {        boolean result = false;        try {            result = jedisCluster.exists(key);            logger.debug("exists {}", key);        } catch (Exception e) {            logger.warn("exists {}", key, e);        } finally {//          returnResource(jedis);        }        return result;    }    @Override    public   boolean existsObject(String key) {        boolean result = false;        try {            result = jedisCluster.exists(getBytesKey(key));            logger.debug("existsObject {}", key);        } catch (Exception e) {            logger.warn("existsObject {}", key, e);        } finally {//          returnResource(jedis);        }        return result;    }    /**     * 获取byte[]类型Key     * @param key     * @return     * @throws UnsupportedEncodingException      */    public static  byte[] getBytesKey(Object object){        if(object instanceof String){            return StringUtils.getBytes((String)object);        }else{            return SerializeUtil.serialize(object);        }    }    /**     * Object转换byte[]类型     * @param key     * @return     */    public static  byte[] toBytes(Object object){        return SerializeUtil.serialize(object);    }    /**     * byte[]型转换Object     * @param key     * @return     */    public static Object toObject(byte[] bytes){        return SerializeUtil.deserialize(bytes);    }    /**     * @autho 董杨炀     * @time 2017年5月6日 上午11:03:58     * @param key     * @param value     * @return     */    @Override    public long setnx(String key, String value) {        return jedisCluster.setnx(key,value);    }    /**     * @autho 董杨炀     * @time 2017年5月6日 上午11:03:58     * @param key     * @param ttl     */    @Override    public void expire(String key, int ttl) {        jedisCluster.expire(key, ttl);    }    /**     * @autho 董杨炀     * @time 2017年5月6日 上午11:03:58     * @param array     */    @Override    public void del(String[] array) {        jedisCluster.del(array);    }    /**     * @autho 董杨炀     * @time 2017年5月6日 上午11:09:24     * @return     */    @Override    public Pipeline pipelined() {        //TODO redis集群环境获取管道模式执行批量操作        return null;        //TODO redis集群环境批量操作待续    }}
package com.ssm.common.redis;import java.util.HashSet;import java.util.Set;import org.apache.commons.pool2.impl.GenericObjectPoolConfig;import org.springframework.beans.factory.FactoryBean;import org.springframework.beans.factory.InitializingBean;import org.springframework.expression.ParseException;import redis.clients.jedis.HostAndPort;import redis.clients.jedis.JedisCluster;public class JedisClusterFactory implements FactoryBean<JedisCluster>,InitializingBean{        private GenericObjectPoolConfig genericObjectPoolConfig;        private JedisCluster jedisCluster;        private int connectionTimeout;        private int soTimeout;        private int maxRedirections;        private Set<String> jedisClusterNodes;        @Override        public void afterPropertiesSet() throws Exception {               //判断地址是否为空              if(jedisClusterNodes == null || jedisClusterNodes.size() == 0){                  throw new NullPointerException("jedisClusterNodes is null");              }              //构造结点              Set<HostAndPort> haps = new HashSet<HostAndPort>();              for(String node:jedisClusterNodes){                  String[] arr = node.split(":");                  if(arr.length != 2){                      throw new ParseException(0, "node address error!");                  }                  haps.add(new HostAndPort(arr[0],Integer.valueOf(arr[1])));              }              jedisCluster = new JedisCluster(haps, connectionTimeout, soTimeout, maxRedirections, genericObjectPoolConfig);        }        @Override        public JedisCluster getObject() throws Exception {            return jedisCluster;        }        @Override        public Class<?> getObjectType() {            return (this.jedisCluster != null ? this.jedisCluster.getClass()                    : JedisCluster.class);        }        @Override        public boolean isSingleton() {            return true;        }        public GenericObjectPoolConfig getGenericObjectPoolConfig() {            return genericObjectPoolConfig;        }        public void setGenericObjectPoolConfig(                GenericObjectPoolConfig genericObjectPoolConfig) {            this.genericObjectPoolConfig = genericObjectPoolConfig;        }        public JedisCluster getJedisCluster() {            return jedisCluster;        }        public void setJedisCluster(JedisCluster jedisCluster) {            this.jedisCluster = jedisCluster;        }        public int getConnectionTimeout() {            return connectionTimeout;        }        public void setConnectionTimeout(int connectionTimeout) {            this.connectionTimeout = connectionTimeout;        }        public int getSoTimeout() {            return soTimeout;        }        public void setSoTimeout(int soTimeout) {            this.soTimeout = soTimeout;        }        public int getMaxRedirections() {            return maxRedirections;        }        public void setMaxRedirections(int maxRedirections) {            this.maxRedirections = maxRedirections;        }        public Set<String> getJedisClusterNodes() {            return jedisClusterNodes;        }        public void setJedisClusterNodes(Set<String> jedisClusterNodes) {            this.jedisClusterNodes = jedisClusterNodes;        }}
package com.ssm.common.redis;import java.util.List;import java.util.Map;import java.util.Set;import redis.clients.jedis.Pipeline;/** * * 操作redis时真正使用的类 * 具体连接方式由spring注入的客户端类型决定 * @author 353654 * */public class RedisOperate implements IJedisClient{    IJedisClient jedisClient;    public IJedisClient getJedisClient() {        return jedisClient;    }    public void setJedisClient(IJedisClient jedisClient) {        this.jedisClient = jedisClient;    }    @Override    public String get(String key) {        return jedisClient.get(key);    }    @Override    public Object getObject(String key) {        return jedisClient.getObject(key);    }    @Override    public String set(String key, String value, int cacheSeconds) {        return jedisClient.set(key, value, cacheSeconds);    }    @Override    public String setObject(String key, Object value, int cacheSeconds) {        return jedisClient.setObject(key, value, cacheSeconds);    }    @Override    public List<String> getList(String key) {        return jedisClient.getList(key);    }    @Override    public List<Object> getObjectList(String key) {        return jedisClient.getObjectList(key);    }    @Override    public long setList(String key, List<String> value, int cacheSeconds) {        return jedisClient.setList(key, value, cacheSeconds);    }    @Override    public long setObjectList(String key, List<Object> value, int cacheSeconds) {        return jedisClient.setObjectList(key, value, cacheSeconds);    }    @Override    public long listAdd(String key, String... value) {        return jedisClient.listAdd(key, value);    }    @Override    public long listObjectAdd(String key, Object... value) {        return jedisClient.listObjectAdd(key, value);    }    @Override    public Set<String> getSet(String key) {        return jedisClient.getSet(key);    }    @Override    public Set<Object> getObjectSet(String key) {        return jedisClient.getObjectSet(key);    }    @Override    public long setSet(String key, Set<String> value, int cacheSeconds) {        return jedisClient.setSet(key, value, cacheSeconds);    }    @Override    public long setObjectSet(String key, Set<Object> value, int cacheSeconds) {        return jedisClient.setObjectSet(key, value, cacheSeconds);    }    @Override    public long setSetAdd(String key, String... value) {        return jedisClient.setSetAdd(key, value);    }    @Override    public long setSetObjectAdd(String key, Object... value) {        return jedisClient.setSetObjectAdd(key, value);    }    @Override    public Map<String, String> getMap(String key) {        return jedisClient.getMap(key);    }    @Override    public Map<String, Object> getObjectMap(String key) {        return jedisClient.getObjectMap(key);    }    @Override    public String setMap(String key, Map<String, String> value, int cacheSeconds) {        return jedisClient.setMap(key, value, cacheSeconds);    }    @Override    public String setObjectMap(String key, Map<String, Object> value,            int cacheSeconds) {        return jedisClient.setObjectMap(key, value, cacheSeconds);    }    @Override    public String mapPut(String key, Map<String, String> value) {        return jedisClient.mapPut(key, value);    }    @Override    public String mapObjectPut(String key, Map<String, Object> value) {        return jedisClient.mapObjectPut(key, value);    }    @Override    public long mapRemove(String key, String mapKey) {        return jedisClient.mapRemove(key, mapKey);    }    @Override    public long mapObjectRemove(String key, String mapKey) {        return jedisClient.mapObjectRemove(key, mapKey);    }    @Override    public boolean mapExists(String key, String mapKey) {        return jedisClient.mapExists(key, mapKey);    }    @Override    public boolean mapObjectExists(String key, String mapKey) {        return jedisClient.mapObjectExists(key, mapKey);    }    @Override    public long del(String key) {        return jedisClient.del(key);    }    @Override    public long delObject(String key) {        return jedisClient.delObject(key);    }    @Override    public boolean exists(String key) {        return jedisClient.exists(key);    }    @Override    public boolean existsObject(String key) {        return jedisClient.existsObject(key);    }    /**     * 分布式锁模拟     * @autho 董杨炀     * @time 2017年5月6日 上午10:38:35     * @param key     * @param value     * @return     */    @Override    public long setnx(String key, String value) {        return jedisClient.setnx(key,value);    }    /**     * 为给定  key  设置生存时间,当  key  过期时(生存时间为  0  ),它会被自动删除。     * @autho 董杨炀     * @time 2017年5月6日 上午10:38:35     * @param key     * @param ttl     */    @Override    public void expire(String key, int ttl) {        jedisClient.expire(key,ttl);        }    /**     * 批量解锁     * @autho 董杨炀     * @time 2017年5月6日 上午11:02:32     * @param array     */    @Override    public void del(String[] array) {        jedisClient.del(array);    }    /**     * 获取redis批量提交的对象     * @autho 董杨炀     * @time 2017年5月6日 上午11:08:15     * @return     */    public Pipeline pipelined() {        return jedisClient.pipelined();    }}

redis的缓存策略如上,这里使用单机,博主没有搭建redis集群,Jedis对集群的支持也不是很好,管道批量操作比较复杂.测试例子可以去源码看,下面简单贴一下代码,如何使用

package com.ssm.service.impl;import javax.annotation.Resource;import org.apache.commons.lang3.StringUtils;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.stereotype.Service;import com.ssm.common.exception.BusinessException;import com.ssm.common.redis.RedisOperate;import com.ssm.common.redis.sync.IBusinessLockService;import com.ssm.common.redis.sync.MutexElement;import com.ssm.common.redis.sync.MutexElementType;import com.ssm.dao.UserDao;import com.ssm.domain.UserEntity;import com.ssm.service.UserService;@Service("userService")public class UserServiceImpl implements UserService {    private static Logger logger = LoggerFactory.getLogger(UserServiceImpl.class);    @Resource    private UserDao userDao;    @Resource    private RedisOperate redisOperate;    @Resource    private IBusinessLockService businessLockService;    public UserEntity getUserById(int userId) {        if(userId < 0){            throw new BusinessException("userID不合法");        }        UserEntity user = null;        user = (UserEntity)redisOperate.getObject(String.valueOf(userId));        if(user!=null){            logger.info(user.toString());            return user;        }else{            user = this.userDao.selectByPrimaryKey(userId);              if(user != null){                redisOperate.setObject(String.valueOf(userId), user, 0);            }            return user;        }    }    /**     * @autho 董杨炀     * @time 2017年5月6日 下午12:18:49     * @param user     * @return     */    @Override    public int updateUser(UserEntity user) {        if(user == null || StringUtils.isBlank(String.valueOf(user.getId())) || user.getId()<0){            throw new BusinessException("userId不合法");        }        //获取互斥对象        MutexElement mutexElement = new MutexElement(String.valueOf(user.getId()), "修改用户资料", MutexElementType.USER_UPDATE);        boolean lock = businessLockService.lock(mutexElement, 0);        System.out.println(lock);        if(!lock){            throw new BusinessException("此用户已被锁定,请稍后重试");        }        try {            return userDao.updateByPrimaryKey(user);        } finally {            businessLockService.unlock(mutexElement);//释放锁        }    }}

这里写图片描述

这里写图片描述

这里写图片描述

redis实现业务锁

package com.ssm.common.redis.sync;/** * 互斥对象 * @autho 董杨炀 * @time 2017年5月6日 上午9:18:30 */public class MutexElement {    /**     * 业务标记     * 比如运单号,订单号,或者唯一ID     */    private String businessNo;    /**     * 业务对象描述,如并发更新订单,运单,结清货款,签收等等业务     */    private String businessDesc;    /**     * 锁定业务对象类型     */    private MutexElementType type;    /**     * 锁定时间,默认一分钟     */    private int ttl = 60;    /**     * 构造函数     * @autho 董杨炀     * @time 2017年5月6日 上午9:18:35     * @param businessNo     * @param businessDesc     * @param type     */    public MutexElement(String businessNo, String businessDesc,MutexElementType type) {        this.businessNo = businessNo;        this.businessDesc = businessDesc;        this.type = type;    }    /**      * 获取业务标记  比如运单号订单号或者唯一ID     * @return 业务标记  比如运单号订单号或者唯一ID      */    public String getBusinessNo() {        return businessNo;    }    /**      * 设置业务标记  比如运单号订单号或者唯一ID      * @param businessNo 业务标记  比如运单号订单号或者唯一ID      */    public void setBusinessNo(String businessNo) {        this.businessNo = businessNo;    }    /**      * 获取业务对象描述,如并发更新订单运单结清货款签收等等业务     * @return 业务对象描述,如并发更新订单运单结清货款签收等等业务      */    public String getBusinessDesc() {        return businessDesc;    }    /**      * 设置业务对象描述,如并发更新订单运单结清货款签收等等业务      * @param businessDesc 业务对象描述,如并发更新订单运单结清货款签收等等业务      */    public void setBusinessDesc(String businessDesc) {        this.businessDesc = businessDesc;    }    /**      * 获取锁定业务对象类型     * @return 锁定业务对象类型      */    public MutexElementType getType() {        return type;    }    /**      * 设置锁定业务对象类型      * @param type 锁定业务对象类型      */    public void setType(MutexElementType type) {        this.type = type;    }    /**      * 获取锁定时间默认一分钟     * @return 锁定时间默认一分钟      */    public int getTtl() {        return ttl;    }    /**      * 设置锁定时间默认一分钟      * @param ttl 锁定时间默认一分钟      */    public void setTtl(int ttl) {        this.ttl = ttl;    }    /**     * @autho 董杨炀     * @time 2017年5月6日 上午9:58:56     * @return     */    @Override    public String toString() {        return "MutexElement [businessNo=" + businessNo + ", businessDesc=" + businessDesc + ", type=" + type + ", ttl="                + ttl + "]";    }}
package com.ssm.common.redis.sync;/** * 锁定业务类型 * @autho 董杨炀 * @time 2017年5月6日 上午10:00:00 */public enum MutexElementType {    REPAYMENT_NO("LockRepaymentNo_","结清货款"),    RFC_SIGN("LockRfcSign_","签收"),    WABYILL_SUBMIT("LockWS_", "运单提交"),    ORDER_UPDATE("LockOrder_", "订单更改"),    USER_UPDATE("LockUser_","用户更改");    /**     * 业务前缀     */    private String prefix;    /**     * 具体业务操作描述     */    private String name;    private MutexElementType(String prefix, String name) {        this.prefix = prefix;        this.name = name;    }    /**      * 获取业务前缀     * @return 业务前缀      */    public String getPrefix() {        return prefix;    }    /**      * 设置业务前缀      * @param prefix 业务前缀      */    public void setPrefix(String prefix) {        this.prefix = prefix;    }    /**      * 获取具体业务操作描述     * @return 具体业务操作描述      */    public String getName() {        return name;    }    /**      * 设置具体业务操作描述      * @param name 具体业务操作描述      */    public void setName(String name) {        this.name = name;    }}
package com.ssm.common.redis.sync;import java.util.List;/** * 业务互斥锁服务 * @autho 董杨炀 * @time 2017年5月6日 上午9:11:21 */public interface IBusinessLockService {    /**     * 锁定某个业务对象     * timeout = 0 时,非阻塞调用,如果对象已锁定立刻返回失败     * timeout > 0 时,阻塞调用,如果对象已锁定,会等待直到1)获取锁并返回成功 2)超时并返回失败     * @author 董杨炀     * @date 2017年5月6日 上午9:11:21     * @param mutex 互斥对象     * @param timeout 超时时间,单位:秒     * @return true:锁定成功,false:锁定失败     */    boolean lock(MutexElement mutex, int timeout);    /**     * 解除某个业务对象锁定     * @author 董杨炀     * @date 2017年5月6日 上午9:11:21     * @param mutex 互斥对象     */    void unlock(MutexElement mutex);    /**     * 批量锁定多个业务对象     * timeout = 0 时,非阻塞调用,如果任意对象已锁定立刻返回失败     * timeout > 0 时,阻塞调用,如果任意对象已锁定,会等待直到1)获取锁并返回成功 2)超时并返回失败     * @author 董杨炀     * @date 2017年5月6日 上午9:11:21     * @param mutexes 多个互斥对象     * @param timeout 超时时间,单位:秒     * @return true:锁定成功,false:锁定失败     */    boolean lock(List<MutexElement> mutexes, int timeout);    /**     * 批量解除多个业务对象锁定     * @author 董杨炀     * @date 2017年5月6日 上午9:11:21     * @param mutexes     */    void unlock(List<MutexElement> mutexes);}
package com.ssm.common.redis.sync;import java.util.ArrayList;import java.util.LinkedHashMap;import java.util.List;import javax.annotation.Resource;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.stereotype.Service;import com.ssm.common.exception.BusinessException;import com.ssm.common.redis.RedisOperate;import com.ssm.utils.CollectionUtils;import com.ssm.utils.StringUtils;import redis.clients.jedis.Pipeline;/** * 业务互斥锁服务 * 根据redis setnx命令模拟实现集群锁 * @autho 董杨炀 * @time 2017年5月6日 上午10:05:35*/@Service("businessLockService")public class BusinessLockService implements IBusinessLockService {    private static final Logger LOGGER = LoggerFactory.getLogger(BusinessLockService.class);    @Resource    private RedisOperate redisOperate;    /**     * 锁定某个业务对象      * timeout = 0 时,非阻塞调用,如果对象已锁定立刻返回失败      * timeout > 0时,阻塞调用,如果对象已锁定,会等待直到1)获取锁并返回成功 2)超时并返回失败     * @autho 董杨炀     * @time 2017年5月6日 上午10:05:35     * @param mutex  互斥对象     * @param timeout 超时时间,单位:秒     * @return true:锁定成功,false:锁定失败     */    @Override    public boolean lock(MutexElement mutex, int timeout) {        if (mutex == null || mutex.getType() == null                || StringUtils.isEmpty(mutex.getBusinessNo())) {            throw new BusinessException("The mutex parameter is empty");        }        String key = mutex.getType().getPrefix() + mutex.getBusinessNo();        String value = mutex.getBusinessDesc();        long nano = System.nanoTime();        try {            do {                LOGGER.debug("try lock key: " + key);                // 使用setnx模拟锁                Long i = redisOperate.setnx(key, value);                if (i == 1) {   // setnx成功,获得锁                    redisOperate.expire(key, mutex.getTtl());                    LOGGER.debug("get lock, key: " + key + " , expire in " + mutex.getTtl() + " seconds.");                    return true;                } else {    // 存在锁                    if (LOGGER.isDebugEnabled()) {                        String desc = redisOperate.get(key);                        LOGGER.debug("key: " + key + " locked by another business:" + desc);                    }                }                if (timeout == 0) { // 非阻塞调用,则退出                    break;                }                Thread.sleep(1000); // 每秒访问一次            } while ((System.nanoTime() - nano) < timeout * 1000 * 1000 * 1000);            // 得不到锁,返回失败            return false;        } catch (Exception e) {            LOGGER.error(e.getMessage(), e);        }        // 锁不再作为业务的的强制必要条件        // 发生REDIS异常,则不再处理锁        return true;    }    /**     * 解除某个业务对象锁定     * @autho 董杨炀     * @time 2017年5月6日 上午10:05:35     * @param mutex     */    @Override    public void unlock(MutexElement mutex) {        if (mutex == null || mutex.getType() == null                || StringUtils.isEmpty(mutex.getBusinessNo())) {            throw new BusinessException("The mutex parameter is empty");        }        String key = mutex.getType().getPrefix() + mutex.getBusinessNo();        try {            redisOperate.del(key);            LOGGER.debug("release lock, key :" + key);        } catch (Exception e) {            LOGGER.error(e.getMessage(), e);        }     }    /**     * 批量锁定多个业务对象      * @autho 董杨炀     * @time 2017年5月6日 上午10:05:35     * @param mutexes     * @param timeout     * @return     */    @Override    public boolean lock(List<MutexElement> mutexes, int timeout) {        if (CollectionUtils.isEmpty(mutexes)) {            throw new BusinessException("The mutex parameter is empty");        }        // 定义并构造所有锁MAP        LinkedHashMap<String, MutexElement> map = new LinkedHashMap<String, MutexElement>();        for (MutexElement mutex : mutexes) {            if (mutex == null || mutex.getType() == null                    || StringUtils.isEmpty(mutex.getBusinessNo())) {                throw new BusinessException("The mutex parameter is empty");            }            String key = mutex.getType().getPrefix() + mutex.getBusinessNo();            map.put(key, mutex);        }        try {            List<String> locking = new ArrayList<String>(); // 要锁定的KEY集合            List<String> locked = new ArrayList<String>();  // 已锁定的KEY集合            locking.addAll(map.keySet());            long nano = System.nanoTime();            do {                LOGGER.debug("try lock keys: " + locking);                // 构建pipeline,批量提交                Pipeline pipeline = redisOperate.pipelined();                for (String key : locking) {                    // 使用setnx模拟锁                    pipeline.setnx(key, map.get(key).getBusinessDesc());                }                // 提交redis执行计数                List<Object> results = pipeline.syncAndReturnAll();                for (int i = 0; i < results.size(); ++i) {                    Long result = (Long) results.get(i);                    String key = locking.get(i);                    if (result == 1) {  // setnx成功,获得锁                        redisOperate.expire(key, map.get(key).getTtl());                        locked.add(key);                    }// 存在锁                }                locking.removeAll(locked);  // 已锁定资源去除                if (CollectionUtils.isEmpty(locking)) { // 得到所有锁资源                    return true;                } else {    // 部分资源未能锁住                    LOGGER.debug("keys: " + locking + " locked by another business:");                }                if (timeout == 0) { // 非阻塞调用,则退出                    break;                }                Thread.sleep(1000); // 每秒访问一次            } while ((System.nanoTime() - nano) < timeout*10001*10001*10001);            // 得不到锁,释放锁定的部分对象,并返回失败            if (CollectionUtils.isNotEmpty(locked)) {                redisOperate.del(locked.toArray(new String[0]));            }            return false;        }catch (Exception e) {            LOGGER.error(e.getMessage(), e);        }        // 锁不再作为业务的的强制必要条件        // 发生REDIS异常,则不再处理锁        return true;    }    /**     * 批量解锁     * @autho 董杨炀     * @time 2017年5月6日 上午10:05:35     * @param mutexes     */    @Override    public void unlock(List<MutexElement> mutexes) {        if (CollectionUtils.isEmpty(mutexes)) {            throw new BusinessException("The mutex parameter is empty");        }        List<String> keys = new ArrayList<String>();        for (MutexElement mutex : mutexes) {            if (mutex == null || mutex.getType() == null                    || StringUtils.isEmpty(mutex.getBusinessNo())) {                throw new BusinessException("The mutex parameter is empty");            }            String key = mutex.getType().getPrefix() + mutex.getBusinessNo();            keys.add(key);        }           try {            redisOperate.del(keys.toArray(new String[0]));            LOGGER.debug("release lock, keys :" + keys);        } catch (Exception e) {            LOGGER.error(e.getMessage(), e);        }    }}

redis的高级特性.队列,发布/订阅待续.博主也不清楚,多见谅

github地址:https://github.com/15000814726/ssm.git

0 0