基於註解的方式整合Srpingmvc+Redis
項目中原本使用的是手動獲取redis鏈接池的方式進行的與Spring的整合,現在需要修改為註解的形式。初次接觸redis,做個記錄。
1. 首先添加 jackson的jar包, 需要添加的 jar包共有三個,分別為:jackson-annoations-2.4.4.jar,jackson-core-2.4.4.jar,jackson-databind-2.4.4.jar,此項目中使用的是同一版本的jar。
2. 更新redis的配置文件,添加redis緩存管理器配置RedisCacheManager,添加redis緩存配置RedisCacheConfig,更新RedisTemplate,添加對key和value的序列化支持:
<?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:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd "> <!-- 配置RedisTemplate --> <bean id="redisTemplate" class="org.springframework.data.redis.core.StringRedisTemplate"> <property name="connectionFactory" ref="jedisConnectionFactory" />
<!-- 設置key和value的序列化 --> <property name="keySerializer"> <bean class="org.springframework.data.redis.serializer.StringRedisSerializer" /> </property> <property name="valueSerializer"> <bean class="org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer" /> </property> </bean> <!-- 配置JedisConnectionFactory --> <bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" p:host-name="${redis.host}" p:port="${redis.port}" p:password="${redis.pass}" p:pool-config-ref="poolConfig" /> <!-- 配置JedisPoolConfig實例 --> <bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig"> <property name="maxIdle" value="${redis.maxIdle}" /> <property name="testOnBorrow" value="${redis.testOnBorrow}" /> </bean> <!-- 配置RedisCacheConfig --> <bean id="redisCacheConfig" class="com.fh.dao.redis.RedisCacheConfig"> <constructor-arg ref="jedisConnectionFactory" /> <constructor-arg ref="redisTemplate" /> <constructor-arg ref="redisCacheManager" /> </bean> <!-- 配置RedisCacheManager --> <bean id="redisCacheManager" class="org.springframework.data.redis.cache.RedisCacheManager"> <constructor-arg name="redisOperations" ref="redisTemplate" /> <property name="defaultExpiration" value="${redis.expiration}"/> <!-- 此處可以設置項目中用到的緩存名稱,即@Cache* 標簽中的value --> <constructor-arg name="cacheNames"> <set> <value>caiya_a</value> <value>caiya_test</value> <value>sampleCache1</value> <value>memoryCache</value> <value>scanCache</value> <value>padIndexCache</value> <value>sampleCache1</value> <value>sampleCache1</value> </set> </constructor-arg> <!--默認緩存名字--> <property name="defaultCacheName" value="caiya_a"/> <!--是否在容器啟動時初始化--> <property name="loadRemoteCachesOnStartup" value="true"/> <!--是否使用前綴--> <property name="usePrefix" value="true"/> <!--前綴命名,僅當usePrefix為true時才生效--> <property name="cachePrefix"> <bean class="org.springframework.data.redis.cache.DefaultRedisCachePrefix"> <constructor-arg name="delimiter" value=":"/> </bean> </property> <!--緩存名字和有效期的分隔符--> <property name="separator" value="#"/> <!--默認有效期1h--> <!-- 多個緩存有效期,一般的單個工程可以省略此項 --> <!-- <property name="expires"> <map> <entry key="caiya_a" value="1800"/> </map> </property> --> </bean> </beans>
3. 創建RedisCacheConfig緩存配置類:
package com.at.dao.redis; import java.lang.reflect.Method; import org.springframework.cache.CacheManager; 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.RedisConnectionFactory; import org.springframework.data.redis.connection.jedis.JedisConnectionFactory; import org.springframework.data.redis.core.RedisTemplate; /** * 以Spring與配置文件來管理的redis緩存配置類 * * 必須添加EnableCaching註解,才能正常啟用緩存功能 * * @author at * 2018-3-15 */ @Configuration @EnableCaching public class RedisCacheConfig extends CachingConfigurerSupport { private volatile JedisConnectionFactory mJedisConnectionFactory; private volatile RedisTemplate<String, String> mRedisTemplate; private volatile RedisCacheManager mRedisCacheManager; public RedisCacheConfig() { super(); } public RedisCacheConfig(JedisConnectionFactory mJedisConnectionFactory, RedisTemplate<String, String> mRedisTemplate, RedisCacheManager mRedisCacheManager) { super(); this.mJedisConnectionFactory = mJedisConnectionFactory; this.mRedisTemplate = mRedisTemplate; this.mRedisCacheManager = mRedisCacheManager; } public JedisConnectionFactory redisConnectionFactory() { return mJedisConnectionFactory; } public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory cf) { return mRedisTemplate; } public CacheManager cacheManager(RedisTemplate<?, ?> redisTemplate) { return mRedisCacheManager; } @Bean public KeyGenerator customKeyGenerator() { return new KeyGenerator() { @Override public Object generate(Object o, Method method, Object... objects) { StringBuilder sb = new StringBuilder(); sb.append(o.getClass().getName()); sb.append(method.getName()); for (Object obj : objects) { sb.append(obj.toString()); } return sb.toString(); } }; } }
4. 更新實體類使其實現序列化,其中:@JsonNaming是jackson 2.1+版本的註解,作用於類或方法,註意這個註解是在jackson-databind包中而不是在jackson-annotations包裏,它可以讓你定制屬性命名策略。@JsonSerialize 用來實現實體類的序列化。
5. 添加對應的dao接口,因此項目使用的是SqlSessionTemplate操作的dao層,此處不再展示代碼。
6. 添加 service和serviceimpl。在接口方法的實現上和dao層都可以添加@Cache*註解,此項目中主要添加在service的方法實現上。
// 此註解是將該方法的返回值放入value的緩存下的key的值中,首次請求該方法時會處理緩存。再次請求該方法時,將先查找緩存中是否有對應的key,如果有則跳過方法執行。 @Cacheable(value="value",key="‘key‘") public List<PageData> getModel(PageData pd) throws Exception { System.out.println("調用了方法"); return (List<PageData>) dao.getModel(pd); } // 此註解跟上面的註解功能相同,但不同的是,該註解將不會使方法跳過執行,而是每次執行後都將新的返回結果更新到value下的key中 @CachePut(value="value", key="‘key‘") public String updateEndTime(String arg1) { return arg1; } // 此註解將會使緩存中的key清除. @CacheEvict(value="figure", key="‘figureList‘",beforeInvocation=true) public int updateFigure(PageData pd) throws Exception{ System.out.println("調用了方法"); return (int) dao.update("CarouseFigureMapper.updateFigure", pd); }
註意:這些註解中都有的相同的參數為:value,key, condition。value表示使用哪個緩存,是必須指定的參數。key屬性是用來指定Spring緩存方法的返回結果時對應的key的。該屬性支持SpringEL表達式。當我們沒有指定該屬性時,Spring將使用默認策略生成key。condition屬性可以設置是否使用緩存:condition屬性默認為空,表示將緩存所有的調用情形。其值是通過SpringEL表達式來指定的,當為true時表示進行緩存處理;當為false時表示不進行緩存處理,即每次調用該方法時該方法都會執行一次。在@CacheEvict註解中,有兩個新的參數,allEntries和beforeInvocation。其中allEntries是boolean類型,表示是否需要清除緩存中的所有元素。默認為false,表示不需要。當指定了allEntries為true時,Spring Cache將忽略指定的key。beforeInvocation可以設置緩存清除的觸發時機,清除操作默認是在對應方法成功執行之後觸發的,即方法如果因為拋出異常而未能成功返回時也不會觸發清除操作。當我們指定該屬性值為true時,Spring會在調用該方法之前清除緩存中的指定元素。
7. 註意事項:註解需要使用在public方法上。帶有@Cache* 註解的方法不能被定義在調用該方法的類裏,例如controller調用方法A,方法A使用註解,則A不能定義在該controller中。
8. 此處不再記錄詳細的接口實現等。關於redis更多的學習及使用方法,將在以後持續記錄。
基於註解的方式整合Srpingmvc+Redis