Maven整合SSM和Redis,親測

易小凡_ivan發表於2018-11-02

Maven、SSM整合Redis

Maven和SSM的搭建這裡就不說了,主要寫Maven、SSM如何整合Redis。

整體的專案框架圖:

專案結構圖

專案結構圖

目錄

Maven、SSM整合Redis

1.1 新增jar包

1.2 新增一個redis.properties檔案

1.3 配置一個spring-redis.xml檔案

1.4  配置spring-mybatis.xml

1.5 新增攔截器MethodCacheInterceptor

1.6 新增Redis操作類RedisUtil

1.7 實體類必須序列化

1.8 完整的專案打包如下:


1.1 新增jar包

在pom.xml檔案中新增Redis所需的jar包

注意,本框架使用的是spring 4.3.14.RELEASE版本,redis 2.9.0版本的,spring-redis 1.8.10.RELEASE版本的,一定要看好版本,有的版本是不支援的。

另外本框架使用的是spring面向切面引入的Redis

<!-- spring版本號 -->

<spring.version>4.3.14.RELEASE</spring.version>

<!-- mybatis版本號 -->

<mybatis.version>3.2.6</mybatis.version>

<!-- redis客戶端jar -->

<dependency>

         <groupId>redis.clients</groupId>

         <artifactId>jedis</artifactId>

         <version>2.9.0</version>

</dependency>

<!-- spring-redis實現 -->

<dependency>

         <groupId>org.springframework.data</groupId>

         <artifactId>spring-data-redis</artifactId>

         <version>1.8.10.RELEASE</version>

</dependency>

<!-- spring 切面外掛 start -->

<dependency>

         <groupId>aopalliance</groupId>

         <artifactId>aopalliance</artifactId>

         <version>1.0</version>

</dependency>

<dependency>

         <groupId>aspectj</groupId>

         <artifactId>aspectjrt</artifactId>

         <version>1.5.4</version>

</dependency>

<dependency>

         <groupId>org.aspectj</groupId>

         <artifactId>aspectjweaver</artifactId>

         <version>1.9.2</version>

</dependency>

<!-- spring 切面外掛 end-->

 

1.2 新增一個redis.properties檔案

此檔案用來配置Redis。

# Redis settings

redis.host=127.0.0.1

redis.port=6379

redis.pass=

redis.maxIdle=400

redis.maxTotal=6000

redis.maxWaitMillis=1000

redis.blockWhenExhausted=true

redis.testOnBorrow=true

redis.timeout=100000

defaultCacheExpireTime=3600

 

1.3 配置一個spring-redis.xml檔案

此檔案用來Spring管理Redis。

<?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" xmlns:aop="http://www.springframework.org/schema/aop"

         xmlns:tx="http://www.springframework.org/schema/tx"

         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/mvc

                        http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd

                        http://www.springframework.org/schema/aop

                        http://www.springframework.org/schema/aop/spring-aop-4.0.xsd

                        http://www.springframework.org/schema/tx

                        http://www.springframework.org/schema/tx/spring-tx.xsd">

 

         <!-- redis資料來源 -->

         <bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">

                  <!-- 最大空閒數 -->

                  <property name="maxIdle" value="${redis.maxIdle}" />

                  <!-- 最大空連線數 -->

                  <property name="maxTotal" value="${redis.maxTotal}" />

                  <!-- 最大等待時間 -->

                  <property name="maxWaitMillis" value="${redis.maxWaitMillis}" />

                  <!-- 連線超時時是否阻塞,false時報異常,ture阻塞直到超時, 預設true -->

                  <property name="blockWhenExhausted" value="${redis.blockWhenExhausted}" />

                  <!-- 返回連線時,檢測連線是否成功 -->

                  <property name="testOnBorrow" value="${redis.testOnBorrow}" />

         </bean>

         <!-- Spring-redis連線池管理工廠 -->

         <bean id="jedisConnectionFactory"

                  class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"

                  p:hostName="${redis.host}" p:port="${redis.port}" p:password="${redis.pass}"

                  p:timeout="${redis.timeout}" p:poolConfig-ref="poolConfig" p:usePool="true">

         </bean>

         <!-- redis template definition -->

         <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">

                  <property name="connectionFactory" ref="jedisConnectionFactory" />

                  <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>

                  <!--開啟事務 -->

                  <property name="enableTransactionSupport" value="true"></property>

         </bean>

         <!-- 快取攔截器配置 -->

         <bean id="methodCacheInterceptor" class="com.ivan.redis.MethodCacheInterceptor">

                  <property name="redisUtil" ref="redisUtil" />

                  <property name="defaultCacheExpireTime" value="${defaultCacheExpireTime}" />

                  <!-- 禁用快取的類名列表 -->

                  <property name="targetNamesList">

                          <list>

                                   <value></value>

                          </list>

                  </property>

                  <!-- 禁用快取的方法名列表 -->

                  <property name="methodNamesList">

                          <list>

                                   <value>add</value>

                                   <value>delete</value>

                                   <value>edit</value>

                          </list>

                  </property>

         </bean>

         <bean id="redisUtil" class="com.ivan.redis.RedisUtil">

                  <property name="redisTemplate" ref="redisTemplate" />

         </bean>

         <!--配置切面攔截方法 -->

         <aop:config proxy-target-class="true">

         <!-- <aop:pointcut id="controllerMethodPointcut"

                          expression="execution(* com.ivan.service.impl.*.get*(..))" /> -->

                  <aop:pointcut id="controllerMethodPointcut"

                          expression="execution(* com.ivan.service.impl.*.*(..))" />

                  <aop:advisor advice-ref="methodCacheInterceptor"

                          pointcut-ref="controllerMethodPointcut" />

         </aop:config>

</beans>

 

1.4  配置spring-mybatis.xml

在spring-mybatis.xml中首先引入redis.properties,然後再引入spring-redis.xml。

<!-- 引入配置檔案 -->

<bean id="propertyConfigurer"

         class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">

         <property name="locations">

                  <list>

                          <value>classpath:jdbc.properties</value>                            

                          <value>classpath:redis.properties</value>

                  </list>

         </property>

         <!--這個配置告訴spring,當某個placeholder無法找到時,

         先不要報錯,並嘗試用另一個PropertyPlaceholderConfigurer來設定placeholder的值。 -->

         <!-- <property name="ignoreUnresolvablePlaceholders" value="true"></property> -->

</bean>

<!-- redis配置 -->

<import resource="spring-redis.xml" />

 

1.5 新增攔截器MethodCacheInterceptor

package com.ivan.redis;

import com.ivan.redis.RedisUtil;

import org.aopalliance.intercept.MethodInterceptor;

import org.aopalliance.intercept.MethodInvocation;

import java.util.List;

//Redis快取過濾器

public class MethodCacheInterceptor implements MethodInterceptor {

         private RedisUtil redisUtil;

         private List<String> targetNamesList; // 禁用快取的類名列表

         private List<String> methodNamesList; // 禁用快取的方法列表

         private String defaultCacheExpireTime; // 快取預設的過期時間

         @Override

         public Object invoke(MethodInvocation invocation) throws Throwable {

                  Object value = null;

                  String targetName = invocation.getThis().getClass().getName();

                  String methodName = invocation.getMethod().getName();

                  if (!isAddCache(targetName, methodName)) {

                          // 跳過快取返回結果

                          return invocation.proceed();

                  }

                  Object[] arguments = invocation.getArguments();

                  String key = getCacheKey(targetName, methodName, arguments);

                  try {

                          // 判斷是否有快取

                          if (redisUtil.exists(key))

                                   return redisUtil.get(key);

                          // 寫入快取

                          // 不存在執行資料庫操作

                          value = invocation.proceed();

                          if (value != null) {

                                   final String tkey = key;

                                   final Object tvalue = value;

                                   new Thread(new Runnable() {

                                            @Override

                                            public void run() {

                                                     // 將查詢的物件存入redis快取

                                                     redisUtil.set(tkey, tvalue, Long.parseLong(defaultCacheExpireTime));

                                            }

                                   }).start();

                          }

                  } catch (Exception e) {

                          e.printStackTrace();

                          if (value == null)

                                   return invocation.proceed();

                  }

                  return value;

         }

         // 是否加入快取

         private boolean isAddCache(String targetName, String methodName) {

                  if (targetNamesList.contains(targetName) || targetName.contains("$$EnhancerBySpringCGLIB$$")) {

                          redisUtil.deleteKeys("*");

                          return false;

                  }

                  for (String methName : methodNamesList) {

                          if (methodName.contains(methName)) {

                                   redisUtil.deleteKeys("*");

                                   return false;

                          }

                  }

                  return true;

         }

         // 建立快取key

         private String getCacheKey(String targetName, String methodName, Object[] arguments) {

                  StringBuffer sbu = new StringBuffer();

                  sbu.append(targetName).append("_").append(methodName);

                  if ((arguments != null) && (arguments.length != 0)) {

                          for (int i = 0; i < arguments.length; i++) {

                                   sbu.append("_").append(arguments[i]);

                          }

                  }

                  return sbu.toString();

         }

         public void setRedisUtil(RedisUtil redisUtil) {

                  this.redisUtil = redisUtil;

         }

         public void setTargetNamesList(List<String> targetNamesList) {

                  this.targetNamesList = targetNamesList;

         }

         public void setMethodNamesList(List<String> methodNamesList) {

                  this.methodNamesList = methodNamesList;

         }

         public void setDefaultCacheExpireTime(String defaultCacheExpireTime) {

                  this.defaultCacheExpireTime = defaultCacheExpireTime;

         }

}

 

1.6 新增Redis操作類RedisUtil

package com.ivan.redis;

import java.io.Serializable;

import java.util.Set;

import java.util.concurrent.TimeUnit;

import org.springframework.data.redis.core.RedisTemplate;

import org.springframework.data.redis.core.ValueOperations;

//Redis工具類

public class RedisUtil {

            private RedisTemplate<Serializable, Object> redisTemplate;

            // 批量刪除對應的value

            public void remove(final String... keys) {

                       for (String key : keys)

                                   remove(key);

            }

            // 批量刪除key

            public void removePattern(final String pattern) {

                       Set<Serializable> keys = redisTemplate.keys(pattern);

                       if (keys.size() > 0)

                                   redisTemplate.delete(keys);

            }

            // 刪除對應的value

            public void remove(final String key) {

                       if (exists(key))

                                   redisTemplate.delete(key);

            }

            // 刪除符合要求的key by ivan

            public void deleteKeys(final String key) {

                       redisTemplate.delete(redisTemplate.keys(key));

            }

            // 判斷快取中是否有對應的value

            public boolean exists(final String key) {

                       return redisTemplate.hasKey(key);

            }

            // 讀取快取

            public Object get(final String key) {

                       Object result = null;

                       ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();

                       result = operations.get(key);

                       return result;

            }

            // 寫入快取

            public boolean set(final String key, Object value) {

                       boolean result = false;

                       try {

                                   ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();

                                   operations.set(key, value);

                                   result = true;

                       } catch (Exception e) {

                                   e.printStackTrace();

                       }

                       return result;

            }

            // 寫入快取

            public boolean set(final String key, Object value, Long expireTime) {

                       boolean result = false;

                       try {

                                   ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();

                                   operations.set(key, value);

                                   redisTemplate.expire(key, expireTime, TimeUnit.SECONDS);

                                   result = true;

                       } catch (Exception e) {

                                   e.printStackTrace();

                       }

                       return result;

            }

            public void setRedisTemplate(RedisTemplate<Serializable, Object> redisTemplate) {

                       this.redisTemplate = redisTemplate;

            }

}

 

1.7 實體類必須序列化

package com.ivan.pojo;

import java.io.Serializable;

//要想使用redis存物件,一定要讓實體類實現Serializable介面,否則會報錯

public class PojoParent implements Serializable{

         private static final long serialVersionUID = 1L;

}

 

1.8 Mybatis必須開啟快取機制,非必須,只有配合用cache快取的時候用

mybatis-config.xml中新增如下語句:

<settings>

          <!-- 二級快取開啟 -->

    <setting name="cacheEnabled" value="true"/>

    <setting name="lazyLoadingEnabled" value="false"/>

    <setting name="aggressiveLazyLoading" value="true"/>

</settings>

 

1.8 完整的專案打包請去我的部落格地址下載:

https://download.csdn.net/download/hello_me_you/10759565

 

相關文章