基於註解的SpringAOP Redis緩衝技術

來源:互聯網
上載者:User

這篇博文主要介紹如何使用SpringAOP + Redis +註解的方式實現緩衝的開發。 一、術語說明 1、SpringAOP AOP(Aspect Oriented Programming),也就是面向方面編程的技術。AOP基於IOC基礎,是對OOP的有益補充。SpringAOP的可配置式,使得代碼幾乎沒有耦合侵入。
2、Redis Redis是一個開源的使用ANSI C語言編寫、支援網路、可基於記憶體亦可持久化的日誌型、Key-Value資料庫,並提供多種語言的API。Redis已經成為NOSQL的典範。 3、註解 採用註解的方式,使得代碼沒有侵入,動態可配置式。 二、思路 在資料沒有變化的時候,採用本機資料,如果資料有了變化,那麼將從資料庫擷取最新資料,並緩衝到本地(可以通過各種方式的緩衝,比如HTML5可以採用localStorge),參照下圖 三、主要程式碼片段 1、pom.xml,用來整合Spring和Redis

<!-- redis 快取資料庫.....start --><dependency><groupId>org.springframework.data</groupId><artifactId>spring-data-redis</artifactId><version>1.6.1.RELEASE</version></dependency><dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><version>2.7.3</version></dependency><!-- redis cache related.....end -->

2、Spring-dispather
<aop:aspectj-autoproxy proxy-target-class="true"/>
3、SpringContent,配置Redis串連
<!-- Redis和緩衝配置開始 --><!-- jedis 配置 --><bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig" >      <property name="maxIdle" value="${redis.maxIdle}" />      <property name="maxWaitMillis" value="${redis.maxWait}" />      <property name="testOnBorrow" value="${redis.testOnBorrow}" /></bean ><!-- redis伺服器中心 --><bean id="connectionFactory"  class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" >      <property name="poolConfig" ref="poolConfig" />      <property name="port" value="${redis.port}" />      <property name="hostName" value="${redis.host}" />      <!-- <property name="password" value="${redis.password}" /> -->      <property name="timeout" value="${redis.timeout}" ></property></bean ><bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate" >      <property name="connectionFactory" ref="connectionFactory" />      <property name="keySerializer" >          <bean class="org.springframework.data.redis.serializer.StringRedisSerializer" />      </property>      <property name="valueSerializer" >          <bean class="org.springframework.data.redis.serializer.StringRedisSerializer" />      </property></bean ><!-- cache配置 --><bean id="putCache" class="com.ninesky.framework.PutCacheAOP" >      <property name="redisTemplate" ref="redisTemplate" /></bean><!-- cache配置 --> <bean id="getCache" class="com.ninesky.framework.GetCacheAOP" >       <property name="redisTemplate" ref="redisTemplate" /> </bean> <!-- Redis和緩衝配置結束 -->
4、Redis.properties
#redis中心#綁定的主機地址redis.host=127.0.0.1#指定Redis監聽連接埠,預設連接埠為6379redis.port=6379 #授權密碼(本例子沒有使用)redis.password=#最大空閑數:空閑連結數大於maxIdle時,將進行回收redis.maxIdle=100  #最大串連數:能夠同時建立的“最大連結個數”redis.maxActive=300  #最大等待時間:單位msredis.maxWait=1000   #使用串連時,檢測串連是否成功 redis.testOnBorrow=true #當用戶端閑置多長時間後關閉串連,如果指定為0,表示關閉該功能redis.timeout=10000 
5、自訂註解 (1)產生緩衝版本PutCache.java
/** * 自訂註解,在插入、更新或者刪除的時候更新對應的版本 * @author Chenth */@Retention(RetentionPolicy.RUNTIME)@Target({ElementType.METHOD})public @interface PutCache {String name() default "";String value() default "";}
(2)擷取緩衝版本GetCache.java
/** * 自訂註解,對於查詢使用緩衝的方法加入該註解 * @author Chenth */@Retention(RetentionPolicy.RUNTIME)@Target({ElementType.METHOD})public @interface GetCache {String name() default "";String value() default "";}
6、加入AOP (1)、GetCache對應的切面
@Aspectpublic class GetCacheAOP {private RedisTemplate<Serializable, Object> redisTemplate;ThreadLocal<Long> time=new ThreadLocal<Long>();ThreadLocal<String> tag=new ThreadLocal<String>();@Pointcut("@annotation(com.ninesky.classtao.springaop.annotation.GetCache)")public void getCache(){System.out.println("我是一個切入點");}/** * 在所有標註@getCache的地方切入 * @param joinPoint */@Before("getCache()")public void beforeExec(JoinPoint joinPoint){MethodSignature ms=(MethodSignature) joinPoint.getSignature();Method method=ms.getMethod();String ActionName = method.getAnnotation(GetCache.class).name();String fieldList = method.getAnnotation(GetCache.class).value();for (String field:fieldList.split(",")) {if ("school_id".equals(field))ActionName+="#"+ActionUtil.getSchoolID();else if ("user_id".equals(field))ActionName+="#"+ActionUtil.getUserID();else if ("user_type".equals(field))ActionName+="#"+ActionUtil.getUserType();else ActionName+="#"+ActionUtil.getParameter(field);}ValueOperations<Serializable, Object> operations =redisTemplate.opsForValue();ActionUtil.setCache(true);//如果是第一次取值.則將版本存放到redis資料庫if (operations.get(ActionName)==null)  {operations.increment(ActionName, 1);return;}if (operations.get(ActionName).equals(ActionUtil.getParameter("cache_version"))) throw new CacheException("資料沒有更新,可以採用本機資料!");ActionUtil.setCache_version(operations.get(ActionName)+"");}public void setRedisTemplate(RedisTemplate<Serializable, Object> redisTemplate) {this.redisTemplate = redisTemplate;}}
(2)、PutCache對應的切面
@Aspectpublic class PutCacheAOP {private RedisTemplate<Serializable, Object> redisTemplate;ThreadLocal<Long> time=new ThreadLocal<Long>();ThreadLocal<String> tag=new ThreadLocal<String>();@Pointcut("@annotation(com.ninesky.classtao.springaop.annotation.PutCache)")public void PutCache(){System.out.println("我是一個切入點");}/** * 在所有標註@PutCache的地方切入 * @param joinPoint */@After("PutCache()")public void AfterExec(JoinPoint joinPoint){MethodSignature ms=(MethodSignature) joinPoint.getSignature();Method method=ms.getMethod();String ActionName = method.getAnnotation(PutCache.class).name();String fieldList = method.getAnnotation(PutCache.class).value();for (String field:fieldList.split(",")) ActionName+="#"+ActionUtil.getParameter(field);ValueOperations<Serializable, Object> operations =redisTemplate.opsForValue();operations.increment(ActionName, 1);}public void setRedisTemplate(RedisTemplate<Serializable, Object> redisTemplate) {this.redisTemplate = redisTemplate;}}
7、最後,在Controller中添加註解
/** * 添加訊息(校園風采、黨建) * @param request */@PutCache(name="newsList",value="school_id,news_code")@RequestMapping(value="/addNews")public @ResponseBody Object addNews(HttpServletRequest request){NewsVO vo = BeanUtil.formatToBean(NewsVO.class);newsService.addNews(vo);newsService.addInformation(vo);return ResponseUtils.sendSuccess(vo);}/** * 擷取訊息列表(Web) * @param request * @return */@GetCache(name="newsList",value="school_id,news_code")@RequestMapping(value="/getNewsListForWeb")public @ResponseBody Object getNewsList(HttpServletRequest request){NewsVO vo = BeanUtil.formatToBean(NewsVO.class);if(IntegerUtil.isEmpty(vo.getSchool_id()))vo.setSchool_id(ActionUtil.getSchoolID());List<NewsVO> list = newsService.getNewsList(vo);return ResponseUtils.sendSuccess(list);}
8、成功了,該方法降低了應用的資料庫請求次數和時間消耗,提高了查詢效率


相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.