SSM框架(二级缓存)集成Redis单机模式及哨兵模式

项目整体框架: SpringMVC + Spring+MyBatis +Redis(缓存部署在Linux虚拟机)。

数据库:mysql

1、整体架构

  • 参考Ehcache实现MyBatis二级缓存代码(Maven引用对应jar查阅)
  • 使用Spring管理Redis连接池
  • 模仿EhcacheCache,实现RedisCache
2、pom.xml中加入Maven依赖
  • <!--引入项目依赖的jar包 -->
    	<!-- SpringMVC、Spring -->
    	<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
    	<dependencies>
    		<!-- mybatis 二级缓存 -->
    		<dependency>
    		    <groupId>org.mybatis</groupId>
    		    <artifactId>mybatis-ehcache</artifactId>
    		    <version>1.0.0</version>
    		</dependency>
    		<!-- spring集成redis -->
    		<dependency>
    		    <groupId>org.springframework.data</groupId>
    		    <artifactId>spring-data-redis</artifactId>
    		    <version>1.8.6.RELEASE</version>
    		</dependency>
    		<dependency>
    		    <groupId>org.apache.commons</groupId>
    		    <artifactId>commons-lang3</artifactId>
    		    <version>3.4</version>
    		</dependency>
    		<dependency>
    		    <groupId>redis.clients</groupId>
    		    <artifactId>jedis</artifactId>
    		    <version>2.9.0</version>
    		</dependency>
    		<!-- spring session 做session共享部分及单点登录问题 -->
    		<!-- https://mvnrepository.com/artifact/org.springframework.session/spring-session -->
    		<dependency>
    		    <groupId>org.springframework.session</groupId>
    		    <artifactId>spring-session</artifactId>
    		    <version>1.3.1.RELEASE</version>
    		</dependency>
    
    
    		
    		<!--引入pageHelper分页插件 -->
    		<dependency>
    			<groupId>com.github.pagehelper</groupId>
    			<artifactId>pagehelper</artifactId>
    			<version>5.0.0</version>
    		</dependency>
    
    		<!-- MBG -->
    		<!-- https://mvnrepository.com/artifact/org.mybatis.generator/mybatis-generator-core -->
    		<dependency>
    			<groupId>org.mybatis.generator</groupId>
    			<artifactId>mybatis-generator-core</artifactId>
    			<version>1.3.5</version>
    		</dependency>
    
    
    		<dependency>
    			<groupId>org.springframework</groupId>
    			<artifactId>spring-webmvc</artifactId>
    			<version>4.3.7.RELEASE</version>
    		</dependency>
    
    		<!-- 返回json字符串的支持 -->
    		<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
    		<dependency>
    			<groupId>com.fasterxml.jackson.core</groupId>
    			<artifactId>jackson-databind</artifactId>
    			<version>2.8.8</version>
    		</dependency>
    		<!--JSR303数据校验支持;tomcat7及以上的服务器, 
    		tomcat7以下的服务器:el表达式。额外给服务器的lib包中替换新的标准的el
    		-->
    		<!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-validator -->
    		<dependency>
    			<groupId>org.hibernate</groupId>
    			<artifactId>hibernate-validator</artifactId>
    			<version>5.4.1.Final</version>
    		</dependency>
    		<!-- Spring-Jdbc -->
    		<!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc -->
    		<dependency>
    			<groupId>org.springframework</groupId>
    			<artifactId>spring-jdbc</artifactId>
    			<version>4.3.7.RELEASE</version>
    		</dependency>
    		<!--Spring-test -->
    		<!-- https://mvnrepository.com/artifact/org.springframework/spring-test -->
    		<dependency>
    			<groupId>org.springframework</groupId>
    			<artifactId>spring-test</artifactId>
    			<version>4.3.7.RELEASE</version>
    		</dependency>
    		<!-- Spring面向切面编程 -->
    		<!-- https://mvnrepository.com/artifact/org.springframework/spring-aspects -->
    		<dependency>
    			<groupId>org.springframework</groupId>
    			<artifactId>spring-aspects</artifactId>
    			<version>4.3.7.RELEASE</version>
    		</dependency>
    		<!--MyBatis -->
    		<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
    		<dependency>
    			<groupId>org.mybatis</groupId>
    			<artifactId>mybatis</artifactId>
    			<version>3.4.2</version>
    		</dependency>
    		<!-- MyBatis整合Spring的适配包 -->
    		<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis-spring -->
    		<dependency>
    			<groupId>org.mybatis</groupId>
    			<artifactId>mybatis-spring</artifactId>
    			<version>1.3.1</version>
    		</dependency>
    		<!-- 数据库连接池、驱动 -->
    		<!-- https://mvnrepository.com/artifact/c3p0/c3p0 -->
    		<dependency>
    			<groupId>c3p0</groupId>
    			<artifactId>c3p0</artifactId>
    			<version>0.9.1</version>
    		</dependency>
    		<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
    		<dependency>
    			<groupId>mysql</groupId>
    			<artifactId>mysql-connector-java</artifactId>
    			<version>5.1.41</version>
    		</dependency>
    		<!-- (jstl,servlet-api,junit) -->
    		<!-- https://mvnrepository.com/artifact/jstl/jstl -->
    		<dependency>
    			<groupId>jstl</groupId>
    			<artifactId>jstl</artifactId>
    			<version>1.2</version>
    		</dependency>
    
    		<!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
    		<dependency>
    			<groupId>javax.servlet</groupId>
    			<artifactId>javax.servlet-api</artifactId>
    			<version>3.0.1</version>
    			<scope>provided</scope>
    		</dependency>
    		<!-- 日志LOG4J -->
    		<!-- https://mvnrepository.com/artifact/log4j/log4j -->
    		<dependency>
    		    <groupId>log4j</groupId>
    		    <artifactId>log4j</artifactId>
    		    <version>1.2.17</version>
    		</dependency>
    		<!--解决Spring使用slf4j输出日志与log4j冲突的问题-->  
          <dependency>  
              <groupId>org.slf4j</groupId>  
              <artifactId>slf4j-log4j12</artifactId>  
              <version>1.7.13</version>  
          </dependency>  
    		<!-- junit -->
    		<!-- https://mvnrepository.com/artifact/junit/junit -->
    		<dependency>
    			<groupId>junit</groupId>
    			<artifactId>junit</artifactId>
    			<version>4.12</version>
    		</dependency>
    	</dependencies>
    3、Linux虚拟机Redis部署。
  • 3.1.下载解压redis(这里使用redis3.2.6的版本):
      
    cd /usr/software
    wget http://download.redis.io/releases/redis-3.2.6.tar.gz
    tar -zxvf /redis-3.2.6.tar.gz

3.2进行编译安装

	cd redis-3.2.6
	make && make install
3.3进行节点创建,这里为了目录结构清晰,创建一个文件夹进行集群文件的统一存放,并复制配置文件到相应的三个文件夹中

	cd /usr/software
	mkdir redis_cluster //创建集群目录
	cd redis_cluster
	mkdir 6379 7001 7002  //分别代表三个节点    其对应端口 6379 6380 6381
	cd ..
 	//创建7000节点为例,拷贝到7000目录
	 cp /usr/software/redis-3.2.6/redis.conf  ./redis_cluster/6379/
	 //拷贝到7001目录
	 cp /usr/software/redis-3.2.6/redis.conf  ./redis_cluster/6380/
 	//拷贝到7002目录
 	cp /usr/software/redis-3.2.6/redis.conf  ./redis_cluster/6381/

3.4.对应节点配置文件的修改以及sentinel.conf文件的创建配置

6379节点文件的修改:

redis.conf配置文件:

daemonize yes

pidfile "/var/run/redis6379.pid"

port 6379

bind 0.0.0.0

logfile "6379.log"

dbfilename "dump6379.rdb"

sentinel.conf的创建和配置:

port 26379

sentinel monitor mymaster192.168.108.128 6379

6380节点文件的修改:

redis.conf配置文件:

daemonize yes

pidfile "/var/run/redis6380.pid"

port6380

bind 0.0.0.0

logfile "6380.log"

dbfilename "dump6380.rdb"

slaveof 192.168.108.128 6380(映射到主服务器上)

sentinel.conf的创建和配置:

port 26380

sentinel monitor mymaster(主机名) 192.168.108.128 6380


6381节点文件的修改:

redis.conf配置文件:

daemonize yes

pidfile "/var/run/redis6381.pid"

port6381

bind 0.0.0.0

logfile "6381.log"

dbfilename "dump7002.rdb"

slaveof 192.168.108.128 6381(映射到主服务器上)

sentinel.conf的创建和配置:

port 26381

sentinel monitor mymaster192.168.108.128 6381

4.进行集群启动验证

分别在相应的文件夹进行启动:redis-server redis.conf 


并分别启动哨兵监控:redis-sentinel sentinel.conf 



以上是保证了linux下redis哨兵模式的部署成功,接下来是如何及集成到现有的SSM项目框架中

web.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_2_5.xsd" id="WebApp_ID" version="2.5">
  <!-- spring 配置文件加载 -->
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:applicationContext.xml,classpath:spring-jedis-2.xml</param-value>
  </context-param>
  
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
<!--springmvc 配置文件加载 这里我用的是默认位置-->
  <servlet>
    <servlet-name>dispatcherServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>dispatcherServlet</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>
  <!-- 字符编码集过滤 -->
  <filter>
    <filter-name>CharacterEncodingFilter</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <init-param>
      <param-name>encoding</param-name>
      <param-value>utf-8</param-value>
    </init-param>
    <init-param>
      <param-name>forceRequestEncoding</param-name>
      <param-value>true</param-value>
    </init-param>
    <init-param>
      <param-name>forceResponseEncoding</param-name>
      <param-value>true</param-value>
    </init-param>
  </filter>
  <filter-mapping>
    <filter-name>CharacterEncodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
  <filter>
    <filter-name>HiddenHttpMethodFilter</filter-name>
    <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>HiddenHttpMethodFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
  <!-- rest风格 处理 如果不采用restful的可以去掉-->
  <filter>
    <filter-name>HttpPutFormContentFilter</filter-name>
    <filter-class>org.springframework.web.filter.HttpPutFormContentFilter</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>HttpPutFormContentFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
  
  <!-- spring  做session共享 处理单点登录等-->
	<filter>
		<filter-name>springSessionRepositoryFilter</filter-name>
		<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
		</filter>
		<filter-mapping>
		<filter-name>springSessionRepositoryFilter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>
</web-app>
dispatcherServlet-servlet.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:mvc="http://www.springframework.org/schema/mvc"
	xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd
		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">

	<!--SpringMVC的配置文件,包含网站跳转逻辑的控制,配置  -->
	<context:component-scan base-package="com.atguigu" use-default-filters="false">
		<!--只扫描控制器。  -->
		<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
	</context:component-scan>
	
	<!--配置视图解析器,方便页面返回  -->
	<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<property name="prefix" value="/WEB-INF/views/"></property>
		<property name="suffix" value=".jsp"></property>
	</bean>
	
	<!--两个标准配置  -->
	<!-- 将springmvc不能处理的请求交给tomcat -->
	<mvc:default-servlet-handler/>
	<!-- 能支持springmvc更高级的一些功能,JSR303校验,快捷的ajax...映射动态请求 -->
	<mvc:annotation-driven/>

</beans>
applicationContext.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:aop="http://www.springframework.org/schema/aop"
	xmlns:tx="http://www.springframework.org/schema/tx"
	xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
		http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">

	<context:component-scan base-package="com.atguigu">
		<context:exclude-filter type="annotation"
			expression="org.springframework.stereotype.Controller" />
	</context:component-scan>
	

	<!-- Spring的配置文件,这里主要配置和业务逻辑有关的 -->
	<!--=================== 数据源,事务控制,xxx ================-->
	<context:property-placeholder location="classpath:dbconfig.properties" />
	<bean id="pooledDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
		<property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property>
		<property name="driverClass" value="${jdbc.driverClass}"></property>
		<property name="user" value="${jdbc.user}"></property>
		<property name="password" value="${jdbc.password}"></property>
	</bean>

	<!--================== 配置和MyBatis的整合=============== -->
	<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
		<!-- 指定mybatis全局配置文件的位置 -->
		<property name="configLocation" value="classpath:mybatis-config.xml"></property>
		<property name="dataSource" ref="pooledDataSource"></property>
		<!-- 指定mybatis,mapper文件的位置 -->
		<property name="mapperLocations" value="classpath:mapper/*.xml"></property>
	</bean>

	<!-- 配置扫描器,将mybatis接口的实现加入到ioc容器中 -->
	<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
		<!--扫描所有dao接口的实现,加入到ioc容器中 -->
		<property name="basePackage" value="com.atguigu.crud.dao"></property>
	</bean>
	
	<!-- 配置一个可以执行批量的sqlSession -->
	<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
		<constructor-arg name="sqlSessionFactory" ref="sqlSessionFactory"></constructor-arg>
		<constructor-arg name="executorType" value="BATCH"></constructor-arg>
	</bean>
	<!--=============================================  -->

	<!-- ===============事务控制的配置 ================-->
	<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<!--控制住数据源  -->
		<property name="dataSource" ref="pooledDataSource"></property>
	</bean>
	
	
	<!--配置事务增强,事务如何切入  -->
	<tx:advice id="txAdvice" transaction-manager="transactionManager">
		<tx:attributes>
			<!-- 所有方法都是事务方法 -->
			<tx:method name="*"/>
			<!--以get开始的所有方法  -->
			<tx:method name="get*" read-only="true"/>
		</tx:attributes>
	</tx:advice>
	<!--开启基于注解的事务,使用xml配置形式的事务(必要主要的都是使用配置式)  -->
	<aop:config>
		<!-- 切入点表达式 -->
		<aop:pointcut expression="execution(* com.atguigu.crud.service..*(..))" id="txPoint"/>
		<!-- 配置事务增强 -->
		<aop:advisor advice-ref="txAdvice" pointcut-ref="txPoint"/>
	</aop:config>
	

	
	<!-- Spring配置文件的核心点(数据源、与mybatis的整合,事务控制) -->
	
</beans>
mybatis-config.xml配置信息:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
  PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
	<settings>
		<setting name="mapUnderscoreToCamelCase" value="true"/>
		 <!-- 全局映射器启用缓存 -->
        <setting name="cacheEnabled" value="true" />
        <!-- 查询时,关闭关联对象即时加载以提高性能 -->
        <setting name="lazyLoadingEnabled" value="true" />
        <!-- 设置关联对象加载的形态,此处为按需加载字段(加载字段由SQL指              定),不会加载关联表的所有字段,以提高性能 -->
        <setting name="aggressiveLazyLoading" value="false" />
        <!-- 对于未知的SQL查询,允许返回不同的结果集以达到通用的效果 -->
        <setting name="multipleResultSetsEnabled" value="true" />
        <!-- 允许使用列标签代替列名 -->
        <setting name="useColumnLabel" value="true" />
        <!-- 允许使用自定义的主键值(比如由程序生成的UUID 32位编码作为键值),数据表的PK生成策略将被覆盖 -->
        <setting name="useGeneratedKeys" value="true" />
        <!-- 给予被嵌套的resultMap以字段-属性的映射支持 -->
        <setting name="autoMappingBehavior" value="FULL" />
        <!-- 对于批量更新操作缓存SQL以提高性能  -->
        <setting name="defaultExecutorType" value="BATCH" />
        <!-- 数据库超过25000秒仍未响应则超时 -->
        <setting name="defaultStatementTimeout" value="25000" />
	</settings>
	<!-- 别名 -->
	<typeAliases>
		<package name="com.atguigu.crud.bean"/>
	</typeAliases>
	

</configuration>

以上是ssm整合的配置信息,下面是集成redis的整合

spring-jedis-2.xml(这里我做了两种的测试,为了配置文件区别,在后面进行了版本识别)

<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:mvc="http://www.springframework.org/schema/mvc"
  xmlns:util="http://www.springframework.org/schema/util"
  xmlns:aop="http://www.springframework.org/schema/aop"
  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.3.xsd
      http://www.springframework.org/schema/util
      http://www.springframework.org/schema/util/spring-util-4.3.xsd
      http://www.springframework.org/schema/mvc
      http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd
      http://www.springframework.org/schema/aop
      http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
      http://www.springframework.org/schema/context
      http://www.springframework.org/schema/context/spring-context-4.3.xsd">
 
 	<!-- session共享部分 -->
	 <bean id="redisHttpSessionConfiguration"
	      class="org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration">
	    <property name="maxInactiveIntervalInSeconds" value="600"/>
	</bean>
    <!-- 连接池基本参数配置,类似数据库连接池 
     <context:property-placeholder location="classpath*:redis.properties" />
    -->
 <bean class="org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration">
	<property name="maxInactiveIntervalInSeconds" value="1800"></property>
</bean>
 
  <!-- 这里为了方便没有引入外部properties文件,实际开发中请注意 -->
<bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
        <property name="maxIdle" value="2000" />
        <property name="maxTotal" value="20000" />
        <property name="minEvictableIdleTimeMillis" value="300000"></property>
        <property name="numTestsPerEvictionRun" value="3"></property>
        <property name="timeBetweenEvictionRunsMillis" value="60000"></property>
        <property name="maxWaitMillis" value="20000" />
        <property name="testOnBorrow" value="false" />
    </bean>
 

	<!-- redis 哨兵模式的配置-->
	<bean id="redisSentinelConfiguration"
		class="org.springframework.data.redis.connection.RedisSentinelConfiguration">
		<!-- master命名配置 需要与服务器sentinel.conf中master命名相同 -->
		<property name="master">
			<bean class="org.springframework.data.redis.connection.RedisNode">
				<property name="name" value="mymaster"></property>
			</bean>
		</property>
		<property name="sentinels">
		 <set>
				<bean class="org.springframework.data.redis.connection.RedisNode">
						<constructor-arg name="host" value="192.168.108.129"></constructor-arg>
						<constructor-arg name="port" value="26379"></constructor-arg>
				</bean>
				<bean class="org.springframework.data.redis.connection.RedisNode">
						<constructor-arg name="host" value="192.168.108.129"></constructor-arg>
						<constructor-arg name="port" value="26380"></constructor-arg>
				</bean>
				<bean class="org.springframework.data.redis.connection.RedisNode">
						<constructor-arg name="host" value="192.168.108.129"></constructor-arg>
						<constructor-arg name="port" value="26381"></constructor-arg>
				</bean>
		  </set>
		</property>
	</bean>  
    <bean id="jedisConnectionFactory"
        class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
       <!--   这里面是单点模式的配置
       <property name="hostName" value="192.168.108.128" /> 
        <property name="port" value="6380" /> -->
        <constructor-arg name="sentinelConfig" ref="redisSentinelConfiguration"></constructor-arg>
        <constructor-arg name="poolConfig" ref="jedisPoolConfig"></constructor-arg>
    </bean>
    
     <!-- 调用连接池工厂配置 -->
    <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
        <property name="connectionFactory" ref="jedisConnectionFactory"></property>
       <!--  如果不配置Serializer,那么存储的时候智能使用String,如果用User类型存储,那么会提示错误User can't cast   
        to String!!!   -->
         <property name="keySerializer">  
            <bean  
            class="org.springframework.data.redis.serializer.StringRedisSerializer" />  
        </property>  
        <property name="valueSerializer">  
            <bean  
                class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer" />  
        </property> 
        <property name="hashKeySerializer">    
            <bean class="org.springframework.data.redis.serializer.StringRedisSerializer"/>    
        </property>    
        <property name="hashValueSerializer">    
            <bean class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer"/>    
        </property>  
    </bean>
    <!-- 使用中间类解决RedisCache.jedisConnectionFactory的静态注入,从而使MyBatis实现第三方缓存 -->
    <bean id="redisCacheTransfer" class="com.atguigu.crud.cache.RedisCacheTransfer">
        <property name="jedisConnectionFactory" ref="jedisConnectionFactory"/>
    </bean> 
    <!-- //End 单机版Redis集成 -->
    
     <!-- Redis缓存管理对象 -->
    <bean id="cacheManager" class="org.springframework.data.redis.cache.RedisCacheManager">
        <constructor-arg index="0" ref="redisTemplate" />
    </bean>
</beans>
以下上java代码

RedisCache2.java

package com.atguigu.crud.cache;

import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

import org.apache.ibatis.cache.Cache;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.connection.jedis.JedisConnection;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;



public class RedisCache2 implements Cache {

    private static JedisConnectionFactory jedisConnectionFactory;
                                          
    private final String id;
    private static final Logger LOGGER = LoggerFactory.getLogger(RedisCache2.class);
    
    private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
    
    public RedisCache2(final String id){
        if (id == null) {
            throw new IllegalArgumentException("cache instances require an ID");
        }
        this.id = id;
    }
    
    
    @Override
    public void clear() {
        RedisConnection connection = null;
        try {
            connection = jedisConnectionFactory.getConnection();
            connection.flushDb();
            connection.flushAll();
        } catch (Exception e) {
            e.printStackTrace();
        }finally{
            if (connection != null) {
                connection.close();
            }
        }
    }

    @Override
    public String getId() {
        return this.id;
    }

    @Override
    public Object getObject(Object key) {
    	LOGGER.info("hahahah");
        System.out.println("查询--------------------------------key:"+key);
        Object result = null;
        RedisConnection connection = null;
        try {
            connection = jedisConnectionFactory.getConnection();
            RedisSerializer<Object> serializer = new JdkSerializationRedisSerializer();
            result = serializer.deserialize(connection.get(serializer.serialize(key)));
        } catch (Exception e) {
            e.printStackTrace();
        }finally{
            if (connection != null) {
                connection.close();
            }
        }
        
        return result;
    }

    @Override
    public ReadWriteLock getReadWriteLock() {
        return this.readWriteLock;
    }

    @Override
    public int getSize() {
        int result = 0;
        RedisConnection connection = null;
        try {
            connection = jedisConnectionFactory.getConnection();
            result = Integer.valueOf(connection.dbSize().toString());
        } catch (Exception e) {
            e.printStackTrace();
        }finally{
            if (connection != null) {
                connection.close();
            }
        }
        return result;
    }

    @Override
    public void putObject(Object key, Object value) {
        System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>key:"+key);
          
        RedisConnection connection = null;
        try {
            connection = jedisConnectionFactory.getConnection();
            RedisSerializer<Object> serializer = new JdkSerializationRedisSerializer();
            System.out.println("**"+serializer.serialize(key));
            connection.set(serializer.serialize(key), serializer.serialize(value));
        } catch (Exception e) {
            e.printStackTrace();
        }finally{
            if (connection != null) {
                connection.close();
            }
        }
        
    }

    @Override
    public Object removeObject(Object key) {
    	RedisConnection connection = null;
        Object result = null;
        try {
            connection = jedisConnectionFactory.getConnection();
            RedisSerializer<Object> serializer = new JdkSerializationRedisSerializer();
            result = connection.expireAt(serializer.serialize(key), 0);
        } catch (Exception e) {
            e.printStackTrace();
        }finally{
            if (connection != null) {
                connection.close();
            }
        }
        return result;
    }


	public static JedisConnectionFactory getJedisConnectionFactory() {
		return jedisConnectionFactory;
	}


	public static void setJedisConnectionFactory(JedisConnectionFactory jedisConnectionFactory) {
		RedisCache2.jedisConnectionFactory = jedisConnectionFactory;
	}
}
RedisCacheTransfer.java

package com.atguigu.crud.cache;

import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;


public class RedisCacheTransfer {
    
    public void setJedisConnectionFactory(JedisConnectionFactory jedisConnectionFactory) {
       RedisCache2.setJedisConnectionFactory(jedisConnectionFactory);
    }
}

User.java

package com.atguigu.crud.bean;

import java.io.Serializable;

public class User implements Serializable{
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private Integer id;
	private String userName;
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public String getUserName() {
		return userName;
	}
	public void setUserName(String userName) {
		this.userName = userName;
	}
}

UserDao.java(这里本人太懒 没有写太多方法)

package com.atguigu.crud.dao;

import com.atguigu.crud.bean.User;

public interface UserDao {
	public User queryByPK(Integer id);
}
UserMapper.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.atguigu.crud.dao.UserDao">
 <cache eviction="LRU" type="com.atguigu.crud.cache.RedisCache2" />
  <select id="queryByPK" resultType="User">
  	select id,name userName from user where id = #{id}
  </select>
</mapper>


IUserService.java
package com.atguigu.crud.service;


import com.atguigu.crud.bean.User;


public interface IUserService {
	public User queryByPK(Integer id);
}
IUserServiceImpl.java

package com.atguigu.crud.service.impl;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.atguigu.crud.bean.User;
import com.atguigu.crud.dao.UserDao;
import com.atguigu.crud.service.IUserService;

@Service
public class IUserServiceImpl implements IUserService{
	@Autowired
	private UserDao userDao;
	@Override
	public User queryByPK(Integer id) {
		// TODO Auto-generated method stub
		return userDao.queryByPK(id);
	}
	public UserDao getUserDao() {
		return userDao;
	}
	public void setUserDao(UserDao userDao) {
		this.userDao = userDao;
	}
	

}

UserController.java

package com.atguigu.crud.controller;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.atguigu.crud.bean.User;
import com.atguigu.crud.service.IUserService;

@Controller
public class UserController {
	@Autowired
	private IUserService iUserService;
	@RequestMapping(value="/user/{id}",method=RequestMethod.GET)
	@ResponseBody
	public User getHello(@PathVariable("id")Integer id,HttpServletRequest request){
		User user = iUserService.queryByPK(id);
		request.getSession().setAttribute("user", user);
		System.out.println(id);
		return user;
	}
	
	public IUserService getiUserService() {
		return iUserService;
	}

	public void setiUserService(IUserService iUserService) {
		this.iUserService = iUserService;
	}
	
}
测试效果:





后台



测试故障转移(关闭主机)





哨兵投票选取了6380端口为主机



测试成功

以上是自己写的小测试 大家发现错误请告诉我下,谢谢

项目源码下载地址

http://download.csdn.net/download/wangxuelei036/9981864


展开阅读全文

没有更多推荐了,返回首页