国产探花免费观看_亚洲丰满少妇自慰呻吟_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ā)表
主站蜘蛛池模板: 云霄县| 泽州县| 桃江县| 德安县| 昌邑市| 沾益县| 汝南县| 高台县| 龙川县| 兴安县| 凤冈县| 仙桃市| 屏南县| 长宁区| 桐城市| 察哈| 文安县| 志丹县| 寿阳县| 缙云县| 武鸣县| 蒲城县| 虞城县| 华蓥市| 玛沁县| 红河县| 井研县| 兴国县| 集安市| 湾仔区| 杂多县| 吉林省| 宁海县| 永川市| 鸡东县| 遵义县| 永靖县| 那曲县| 盐亭县| 弥勒县| 石狮市|