国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 編程 > Java > 正文

Java開發(fā)框架spring實(shí)現(xiàn)自定義緩存標(biāo)簽

2019-11-26 14:45:23
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

自從spring3.1之后,spring引入了抽象緩存,可以通過(guò)在方法上添加@Cacheable等標(biāo)簽對(duì)方法返回的數(shù)據(jù)進(jìn)行緩存。但是它到底是怎么實(shí)現(xiàn)的呢,我們通過(guò)一個(gè)例子來(lái)看一下。首先我們定義一個(gè)@MyCacheable

package caching.springaop;  import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import java.lang.annotation.ElementType;  /**  * 使用@MyCacheable注解方法  */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface MyCacheable{  } 

然后定義處理MyCacheable的切面

package caching.springaop;  import java.util.HashMap; import java.util.Map;  import org.apache.log4j.Logger; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut;  /**  * 處理MyCacheable方法的切面  */ @Aspect public class CacheAspect {    private Logger logger = Logger.getLogger(CacheAspect.class);   private Map<String, Object> cache;    public CacheAspect() {     cache = new HashMap<String, Object>();   }    /**    * 所有標(biāo)注了@Cacheable標(biāo)簽的方法切入點(diǎn)    */   @Pointcut("execution(@MyCacheable * *.*(..))")   @SuppressWarnings("unused")   private void cache() {   }    @Around("cache()")   public Object aroundCachedMethods(ProceedingJoinPoint thisJoinPoint)       throws Throwable {     logger.debug("Execution of Cacheable method catched");     //產(chǎn)生緩存數(shù)據(jù)的key值,像是這個(gè)樣子caching.aspectj.Calculator.sum(Integer=1;Integer=2;)     StringBuilder keyBuff = new StringBuilder();     //增加類的名字     keyBuff.append(thisJoinPoint.getTarget().getClass().getName());     //加上方法的名字     keyBuff.append(".").append(thisJoinPoint.getSignature().getName());     keyBuff.append("(");     //循環(huán)出cacheable方法的參數(shù)     for (final Object arg : thisJoinPoint.getArgs()) {       //增加參數(shù)的類型和值       keyBuff.append(arg.getClass().getSimpleName() + "=" + arg + ";");     }     keyBuff.append(")");     String key = keyBuff.toString();     logger.debug("Key = " + key);     Object result = cache.get(key);     if (result == null) {       logger.debug("Result not yet cached. Must be calculated...");       result = thisJoinPoint.proceed();       logger.info("Storing calculated value '" + result + "' to cache");       cache.put(key, result);     } else {       logger.debug("Result '" + result + "' was found in cache");          return result;   }  } 

上述代碼展示了如何處理MyCacheable自定義的標(biāo)簽,以及默認(rèn)情況下產(chǎn)生key值的規(guī)則。最后生成的key值大概是這個(gè)樣子:caching.aspectj.Calculator.sum(Integer=1;Integer=2;)
下邊這段代碼在方法上添加了MyCacheable標(biāo)簽

package caching.springaop;  import org.apache.log4j.Logger; public class Calculator {   private Logger logger = Logger.getLogger(Calculator.class);   @MyCacheable   public int sum(int a, int b) {     logger.info("Calculating " + a + " + " + b);     try {       //假設(shè)這是代價(jià)非常高的計(jì)算       Thread.sleep(3000);     } catch (InterruptedException e) {       logger.error("Something went wrong...", e);     }     return a + b;   } } 

在方法上加了MyCacheable標(biāo)簽,當(dāng)key值相同的情況下會(huì)直接在緩存中獲取數(shù)據(jù),如果沒有相同的key值,則會(huì)重新計(jì)算,因?yàn)檫@里只是一個(gè)加和操作,耗時(shí)非常的短暫。我們?cè)谶@里讓其睡眠3秒鐘。
我們?cè)趕pring-config.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:aop="http://www.springframework.org/schema/aop"   xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd     http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">   <aop:aspectj-autoproxy />   <bean class="caching.springaop.CacheAspect" />   <bean id="calc" class="caching.springaop.Calculator" /> </beans> 

測(cè)試類:

package caching.springaop;  import org.apache.log4j.Logger; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext;  /**  * 使用SpringAOP緩存的簡(jiǎn)單例子  * @author txxs  */ public class App {    private static Logger logger = Logger.getLogger(App.class);    public static void main(String[] args) {     logger.debug("Starting...");     ApplicationContext ctx = new ClassPathXmlApplicationContext("spring-config.xml");     Calculator calc = (Calculator) ctx.getBean("calc");     //計(jì)算出來(lái)的結(jié)果將會(huì)被存儲(chǔ)在cache     logger.info("1 + 2 = " + calc.sum(1, 2));     //從緩存中獲取結(jié)果     logger.info("1 + 2 = " + calc.sum(1, 2));     logger.debug("Finished!");   }  } 

我們看一下運(yùn)行的結(jié)果:

從結(jié)果來(lái)看第一次直接計(jì)算結(jié)果,第二次從緩存中獲取。

以上就是spring實(shí)現(xiàn)自定義緩存標(biāo)簽的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 青岛市| 密云县| 铁岭县| 德昌县| 松溪县| 屯门区| 丹寨县| 绥江县| 大渡口区| 盐边县| 咸阳市| 梓潼县| 绩溪县| 张家港市| 宝丰县| 闽清县| 梁平县| 马关县| 巴林左旗| 习水县| 青田县| 揭西县| 甘泉县| 西乡县| 屏东市| 巴林右旗| 长子县| 榆树市| 呼伦贝尔市| 裕民县| 饶平县| 双城市| 拜城县| 西峡县| 辽中县| 衡阳县| 临武县| 灌云县| 杨浦区| 淮北市| 左权县|