前幾天在spring整合Redis的時候使用了手動的方式,也就是可以手動的向redis新增快取與清除快取,參考:http://www.cnblogs.com/qlqwjy/p/8562703.html
今天想的將spring註解整合Redis快取弄明白,於是通過查閱資料,先做記錄如下:
大致步驟如下:
0.spring的主配置中宣告註解快取:<cache:annotation-driven cache-manager="redisCacheManager"/>
1.maven的pom.xml檔案匯入架包
2.配置檔案新增配置
3.spring管理bean的生成,xml檔案配置
4. RedisCacheConfig redis自定義的工具類,自定義redis的key生成規則
5.在你想要做快取的地方,使用註解進行快取
- 0.spring的主配置中宣告註解快取:<cache:annotation-driven cache-manager="redisCacheManager"/>
注意:此步驟必須做,必須宣告採用的快取管理器是自己配置的redisCacheManager,否則會報錯。
<cache:annotation-driven cache-manager="redisCacheManager"/>
- 1.maven的pom.xml檔案匯入架包
注意:
引入jackson是為了手動新增快取
<!-- jedis依賴 --> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>2.9.0</version> </dependency> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-redis</artifactId> <version>1.8.4.RELEASE</version> </dependency> <!-- jackson --> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <version>2.1.0</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.1.0</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-annotations</artifactId> <version>2.1.0</version> </dependency>
- 2.配置檔案新增配置redis.properties
#訪問地址
redis.host=127.0.0.1
#訪問埠
redis.port=6379
#注意,如果沒有password,此處不設定值,但這一項要保留
redis.password=
#最大空閒數,資料庫連線的最大空閒時間。超過空閒時間,資料庫連線將被標記為不可用,然後被釋放。設為0表示無限制。
redis.maxIdle=300
#連線池的最大資料庫連線數。設為0表示無限制
redis.maxActive=600
#最大建立連線等待時間。如果超過此時間將接到異常。設為-1表示無限制。
redis.maxWait=1000
#在borrow一個jedis例項時,是否提前進行alidate操作;如果為true,則得到的jedis例項均是可用的;
redis.testOnBorrow=true
- 3.spring管理bean的生成,xml檔案配置 applicationContext-redis.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans" 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/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd "> <!-- 連線池基本引數配置,類似資料庫連線池 --> <context:property-placeholder location="classpath:redis.properties" ignore-unresolvable="true" /> <!-- redis連線池 --> <bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig"> <property name="maxTotal" value="${redis.maxActive}" /> <property name="maxIdle" value="${redis.maxIdle}" /> <property name="testOnBorrow" value="${redis.testOnBorrow}" /> </bean> <!-- 連線池配置,類似資料庫連線池 --> <bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"> <property name="hostName" value="${redis.host}"></property> <property name="port" value="${redis.port}"></property> <!-- <property name="password" value="${redis.pass}"></property> --> <property name="poolConfig" ref="poolConfig"></property> </bean> <!--redis操作模版,使用該物件可以操作redis --> <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate" > <property name="connectionFactory" ref="jedisConnectionFactory" /> <!--如果不配置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.GenericJackson2JsonRedisSerializer" /> </property> <property name="hashKeySerializer"> <bean class="org.springframework.data.redis.serializer.StringRedisSerializer"/> </property> <property name="hashValueSerializer"> <bean class="org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer"/> </property> <!--開啟事務 --> <property name="enableTransactionSupport" value="true"></property> </bean > <!-- 配置RedisCacheManager --> <bean id="redisCacheManager" class="org.springframework.data.redis.cache.RedisCacheManager"> <constructor-arg name="redisOperations" ref="redisTemplate" /> <property name="defaultExpiration" value="${redis.expiration}" /> </bean> <!-- 配置RedisCacheConfig --> <bean id="redisCacheConfig" class="cn.qlq.util.RedisCacheConfig"> <constructor-arg ref="jedisConnectionFactory"/> <constructor-arg ref="redisTemplate"/> <constructor-arg ref="redisCacheManager"/> </bean> <!-- 下面這個是整合Mybatis的二級快取使用的 --> <bean id="redisCacheTransfer" class="cn.qlq.jedis.RedisCacheTransfer"> <property name="jedisConnectionFactory" ref="jedisConnectionFactory" /> </bean> </beans>
JedisPoolConfig jedis連線池配置物件
JedisConnectionFactory jedis連線工廠,生成連線物件
RedisTemplate RedisTemplate 對 RedisConnection 進行了封裝。提供連線管理,序列化等功能,它對 Redis 的互動進行了更高層次的抽象,極大的方便和簡化了 Redis 的操作
RedisCacheManager 做為 redis 統一的排程和管理者
RedisCacheConfig RedisCacheConfig extends org.springframework.cache.annotation.CachingConfigurerSupport,自定義redis的key生成規則,如果不在註解引數中註明key=“”的話,就採用這個類中的key生成規則生成key
- 4. RedisCacheConfig redis自定義的工具類,自定義redis的key生成規則
採用Java配置的方式注入到spring
package cn.qlq.util; import java.lang.reflect.Method; import org.springframework.cache.annotation.CachingConfigurerSupport; import org.springframework.cache.annotation.EnableCaching; import org.springframework.cache.interceptor.KeyGenerator; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.cache.RedisCacheManager; import org.springframework.data.redis.connection.jedis.JedisConnectionFactory; import org.springframework.data.redis.core.RedisTemplate; @EnableCaching @Configuration public class RedisCacheConfig extends CachingConfigurerSupport { private volatile JedisConnectionFactory jedisConnectionFactory; private volatile RedisTemplate<String, String> redisTemplate; private volatile RedisCacheManager redisCacheManager; public RedisCacheConfig() { super(); } /** * 帶引數的構造方法 初始化所有的成員變數 * * @param jedisConnectionFactory * @param redisTemplate * @param redisCacheManager */ public RedisCacheConfig(JedisConnectionFactory jedisConnectionFactory, RedisTemplate<String, String> redisTemplate, RedisCacheManager redisCacheManager) { this.jedisConnectionFactory = jedisConnectionFactory; this.redisTemplate = redisTemplate; this.redisCacheManager = redisCacheManager; } public JedisConnectionFactory getJedisConnecionFactory() { return jedisConnectionFactory; } public RedisTemplate<String, String> getRedisTemplate() { return redisTemplate; } public RedisCacheManager getRedisCacheManager() { return redisCacheManager; } @Bean public KeyGenerator keyGenerator() { return new KeyGenerator() { @Override public Object generate(Object o, Method method, Object... params) { StringBuilder sb = new StringBuilder(); sb.append(o.getClass().getName()); sb.append(method.getName()); for (Object param : params) { sb.append(param.toString()); } return sb.toString(); } }; } }
上面的自定義的key規則是類 本類名+方法名+引數名(中間沒有逗號區分),例如:
Array2List.TestClassAndMethodAndParamfun1{2=ssssssssssssssssss, 1=ssssssssssssssssss}
所以我們可以對上面的自定義規則進行改造,將方法名和引數名進行隔開之後進行區分:(修改過的key的生成規則)
public Object generate(Object o, Method method, Object... params) { //規定 本類名+方法名+引數名 為key StringBuilder sb = new StringBuilder(); sb.append(o.getClass().getName()); sb.append("-"); sb.append(method.getName()); sb.append("-"); for (Object param : params) { sb.append(param.toString()); } return sb.toString(); }
結果:
Array2List.TestClassAndMethodAndParam-fun1-{2=ssssssssssssssssss, 1=ssssssssssssssssss}
- 5.在你想要做快取的地方,使用註解進行快取
先介紹幾個註解
1》@CacheConfig 配置在類上,cacheNames即定義了本類中所有用到快取的地方,都去找這個庫。只要使用了這個註解,在方法上@Cacheable @CachePut @CacheEvict就可以不用寫value去找具體庫名了。【一般不怎麼用】
2》@Cacheable 配置在方法或類上,作用:本方法執行後,先去快取看有沒有資料,如果沒有,從資料庫中查詢出來,給快取中存一份,返回結果,下次本方法執行,在快取未過期情況下,先在快取中查詢,有的話直接返回,沒有的話從資料庫查詢
3》@CachePut 類似於更新操作,即每次不管快取中有沒有結果,都從資料庫查詢結果,並將結果更新到快取,並返回結果
4》@CacheEvict 用來清除用在本方法或者類上的快取資料(用在哪裡清除哪裡)
例子:
最直觀的表現:首次登入,會有一條資料庫的查詢語句在控制檯。
退出再登入,不會執行資料庫的查詢,直接從資料庫中取出快取,登入成功。
說明:
①使用了@Cacheable(value="myUser"),即表示快取中有,直接從快取取出,沒有的話先從資料庫中查出,然後再插入
②如果未在類上使用@CacheConfig註解規定資料要快取到哪個庫中,就必須給value一個值,規定資料最後快取到哪個redis庫中
③因為redis快取資料實際就是鍵值對的形式儲存,因此必須給定key-value的key,這裡沒有給key引數賦值,所以key的生成規則按照上面工具類中規定的key生成的
④key-value的value就是本方法的返回值,如果要快取登入使用者資訊,本方法需要進行修改,返回user物件就可以快取到key-value的value中
例如:
Action:
package cn.qlq.Action; import java.sql.SQLException; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.servlet.http.HttpServletRequest; import org.apache.commons.lang3.Validate; import org.apache.struts2.ServletActionContext; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Controller; import com.github.pagehelper.PageHelper; import com.opensymphony.xwork2.ActionSupport; import cn.qlq.bean.User; import cn.qlq.service.UserService; @Controller @Scope("prototype") @SuppressWarnings("all") public class UserAction extends ActionSupport { private Map<String, Object> response; @Autowired private UserService userService; private int id; private String name; /** * 測試清除註解儲存的快取的同時手動新增單個快取 * * @return */ public String add() { try { userService.addUser(id, name); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } return "add"; } /** * 測試查詢單個的時候註解新增單個快取 * * @return * @throws Exception */ public String find() throws Exception { User user = userService.findUserById(id); HttpServletRequest request = ServletActionContext.getRequest(); request.setAttribute("user", user); return "find"; } /** * 測試刪除單個的時候註解刪除單個快取 * @return */ public String delete() { try { userService.deleteById(id); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } return "delete"; } /** * 測試註解快取,將查出來的集合結果加入快取 * * @return * @throws Exception */ public String findPage() throws Exception { response = new HashMap(); if (name == null) name = "111"; // 第三個引數代表排序方式 PageHelper.startPage(2, 2, "id desc"); List<User> users = userService.findUsersByPage(name); response.put("users", users); return "success"; } public Map getResponse() { return response; } public void setResponse(Map response) { this.response = response; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
Service新增快取與刪除快取:
package cn.qlq.service.impl; import java.sql.SQLException; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cache.annotation.CacheEvict; import org.springframework.cache.annotation.Cacheable; import org.springframework.stereotype.Service; import cn.qlq.bean.User; import cn.qlq.mapper.UserMapper; import cn.qlq.service.UserService; import cn.qlq.util.RedisUtil; @Service public class UserServiceImpl implements UserService { @Autowired private RedisUtil redisUtil; @Autowired private UserMapper userMapper; //查詢出來的時候新增單個快取 @Cacheable(value="user",key="'user'+#id.toString()") @Override public User findUserById(int id) throws Exception { System.out.println("列印語句則沒有走快取"); return userMapper.findUserById(id); } //刪除資料庫的時候刪除redis的快取 @Override @CacheEvict(value="user",key="'user'+#id.toString()") public boolean deleteById(int id){ return true; } //新增快取 @Cacheable(value="Alluser") @Override public List<User> findUsersByPage(String name) throws SQLException { System.out.println("列印語句則沒有走快取"); return userMapper.findUsersByPage(); } //清除上面的快取,同時手動的新增一個快取看能否實現 @CacheEvict(value="Alluser") @Override public int addUser(int id, String name) throws SQLException { redisUtil.set("mykey", "myvalue"); return userMapper.addUser(id, name); } }
解釋:
findUserById()函式將單個使用者存入快取中,例如訪問:http://localhost/SSM/user_find?id=1 後檢視redis:
函式註解上面的user加上~value作為一個zset存入快取,值為具體的快取的鍵:
繼續訪問 http://localhost/SSM/user_find?id=2 http://localhost/SSM/user_find?id=3 http://localhost/SSM/user_find?id=4之後
繼續訪問http://localhost/SSM/user_delete?id=4 刪除一個user4快取:
總結:
此版本的redisspring-data-redis在設定快取的時候是將value的值加上~keys存為一個zset,值就是每個具體的快取的key。例如上面
@Cacheable(value="user",key="'user'+#id.toString()")
就是將user~keys作為一個zset,然後其值為user1.......(快取的鍵)
刪除快取的時候刪除指定的鍵,然後從指定的value加上~keys的zset中刪除對應的值,完成刪除一個快取。
如果刪除的時候只指定了其value,而沒有指定key值,則跟據value值加上~keys作為key找到對應的zset,根據zset值獲取所有的key後刪除,然後刪除此zset即完成刪除。
最後給出這幾個註解的具體引數以及使用相關配圖參考。
表 1. @Cacheable 作用和配置方法
@Cacheable 的作用 主要針對方法配置,能夠根據方法的請求引數對其結果進行快取
表 2. @CachePut 作用和配置方法
@CachePut 的作用 主要針對方法配置,能夠根據方法的請求引數對其結果進行快取,和 @Cacheable 不同的是,它每次都會觸發真實方法的呼叫
@CachePut 主要的引數 | ||
value | 快取的名稱,在 spring 配置檔案中定義,必須指定至少一個 | 例如: @Cacheable(value=”mycache”) 或者 @Cacheable(value={”cache1”,”cache2”} |
key | 快取的 key,可以為空,如果指定要按照 SpEL 表示式編寫,如果不指定,則預設按照方法的所有引數進行組合 | 例如: @Cacheable(value=”testcache”,key=”#userName”) |
condition | 快取的條件,可以為空,使用 SpEL 編寫,返回 true 或者 false,只有為 true 才進行快取 | 例如: @Cacheable(value=”testcache”,condition=”#userName.length()>2”) |
表 3. @CacheEvict 作用和配置方法
@CachEvict 的作用 主要針對方法配置,能夠根據一定的條件對快取進行清空@CacheEvict 主要的引數 | ||
value | 快取的名稱,在 spring 配置檔案中定義,必須指定至少一個 | 例如: @CachEvict(value=”mycache”) 或者 @CachEvict(value={”cache1”,”cache2”} |
key | 快取的 key,可以為空,如果指定要按照 SpEL 表示式編寫,如果不指定,則預設按照方法的所有引數進行組合 | 例如: @CachEvict(value=”testcache”,key=”#userName”) |
condition | 快取的條件,可以為空,使用 SpEL 編寫,返回 true 或者 false,只有為 true 才清空快取 | 例如: @CachEvict(value=”testcache”, condition=”#userName.length()>2”) |
allEntries | 是否清空所有快取內容,預設為 false,如果指定為 true,則方法呼叫後將立即清空所有快取 | 例如: @CachEvict(value=”testcache”,allEntries=true) |
beforeInvocation | 是否在方法執行前就清空,預設為 false,如果指定為 true,則在方法還沒有執行的時候就清空快取,預設情況下,如果方法執行丟擲異常,則不會清空快取 | 例如: @CachEvict(value=”testcache”,beforeInvocation=true) |
*************************************************************************************************************************************************************************************
*************************************************************************************************************************************************************************************
spEL表示式的使用方法:http://docs.spring.io/spring/docs/4.2.x/spring-framework-reference/html/expressions.html
關於註解實現Redis快取的方法,只有將key設計的合理且強大,整個的快取在專案中才能通用且高效。否則,就像我上面的簡單的例子一樣,真的是搞笑了。
總結:
在redis做快取的時候最好是每個快取的生命週期不固定,也就是分散的使快取失效。可以設定有效期為3-9小時。具體的做法就是在Java中產生一個3-9小時的隨機數。
注意:
在IDEA中整合的時候發現用註解配置Bean報錯,因此將上面的KeyGenerator單獨抽成類,注入到Spring中並在cache標籤中指明key生成器:
KeyGenerator.java
package cn.xm.jwxt.utils; import org.springframework.stereotype.Component; import java.lang.reflect.Method; /** * @Author: qlq * @Description * @Date: 22:49 2018/3/25 */ public class KeyGenerator implements org.springframework.cache.interceptor.KeyGenerator { @Override public Object generate(Object o, Method method, Object... params) { //規定 本類名+方法名+引數名 為key StringBuilder sb = new StringBuilder(); sb.append(o.getClass().getName()); sb.append(method.getName()); for (Object param : params) { sb.append(param.toString()); } return sb.toString(); } }
key的生成規則也可以修改為:
public Object generate(Object o, Method method, Object... params) { //規定 本類名+方法名+引數名 為key StringBuilder sb = new StringBuilder(); sb.append(o.getClass().getName()); sb.append("-"); sb.append(method.getName()); sb.append("-"); for (Object param : params) { sb.append(param.toString()); } return sb.toString(); }
RedisCacheConfig.java
package cn.xm.jwxt.utils; import java.lang.reflect.Method; import org.springframework.cache.annotation.CachingConfigurerSupport; import org.springframework.cache.annotation.EnableCaching; import org.springframework.cache.interceptor.KeyGenerator; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.cache.RedisCacheManager; import org.springframework.data.redis.connection.jedis.JedisConnectionFactory; import org.springframework.data.redis.core.RedisTemplate; /** * 註解redis快取整合spring需要使用的配置類 java配置的方式注入bean到spring * @author liqiang * */ public class RedisCacheConfig extends CachingConfigurerSupport { private volatile JedisConnectionFactory jedisConnectionFactory; private volatile RedisTemplate<String, String> redisTemplate; private volatile RedisCacheManager redisCacheManager; public RedisCacheConfig() { super(); } /** * 帶引數的構造方法 初始化所有的成員變數 * * @param jedisConnectionFactory * @param redisTemplate * @param redisCacheManager */ public RedisCacheConfig(JedisConnectionFactory jedisConnectionFactory, RedisTemplate<String, String> redisTemplate, RedisCacheManager redisCacheManager) { this.jedisConnectionFactory = jedisConnectionFactory; this.redisTemplate = redisTemplate; this.redisCacheManager = redisCacheManager; } public JedisConnectionFactory getJedisConnecionFactory() { return jedisConnectionFactory; } public RedisTemplate<String, String> getRedisTemplate() { return redisTemplate; } public RedisCacheManager getRedisCacheManager() { return redisCacheManager; } }
applicationContext-redis.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:cache="http://www.springframework.org/schema/cache" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache-3.2.xsd "> <cache:annotation-driven cache-manager="redisCacheManager" key-generator="keyGenerator"/> <!-- 連線池基本引數配置,類似資料庫連線池 --> <context:property-placeholder location="classpath:redis.properties" ignore-unresolvable="true" /> <!-- redis連線池 --> <bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig"> <property name="maxTotal" value="${redis.maxActive}" /> <property name="maxIdle" value="${redis.maxIdle}" /> <property name="testOnBorrow" value="${redis.testOnBorrow}" /> </bean> <!-- 連線池配置,類似資料庫連線池 --> <bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"> <property name="hostName" value="${redis.host}"></property> <property name="port" value="${redis.port}"></property> <!-- <property name="password" value="${redis.pass}"></property> --> <property name="poolConfig" ref="poolConfig"></property> </bean> <!--redis操作模版,使用該物件可以操作redis --> <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate" > <property name="connectionFactory" ref="jedisConnectionFactory" /> <!--如果不配置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.GenericJackson2JsonRedisSerializer" /> </property> <property name="hashKeySerializer"> <bean class="org.springframework.data.redis.serializer.StringRedisSerializer"/> </property> <property name="hashValueSerializer"> <bean class="org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer"/> </property> <!--開啟事務 --> <property name="enableTransactionSupport" value="true"></property> </bean > <!-- 配置RedisCacheManager --> <bean id="redisCacheManager" class="org.springframework.data.redis.cache.RedisCacheManager"> <constructor-arg name="redisOperations" ref="redisTemplate" /> <property name="defaultExpiration" value="${redis.expiration}" /> </bean> <!-- 配置RedisCacheConfig --> <bean id="redisCacheConfig" class="cn.xm.jwxt.utils.RedisCacheConfig"> <constructor-arg ref="jedisConnectionFactory"/> <constructor-arg ref="redisTemplate"/> <constructor-arg ref="redisCacheManager"/> </bean> <!----> <bean id="keyGenerator" class="cn.xm.jwxt.utils.KeyGenerator"></bean> <!-- 下面這個是整合Mybatis的二級快取使用的 --> <!-- <bean id="redisCacheTransfer" class="cn.qlq.jedis.RedisCacheTransfer"> <property name="jedisConnectionFactory" ref="jedisConnectionFactory" /> </bean>--> </beans>
參考:https://www.cnblogs.com/sxdcgaq8080/p/7228163.html
手動redis註解整合spring:http://www.cnblogs.com/qlqwjy/p/8562703.html
關於快取註解的更詳細的使用方法參考:http://www.cnblogs.com/qlqwjy/p/8559119.html