Java 開発フレームワーク Spring はカスタム キャッシュ タグを実装します

高洛峰
リリース: 2017-01-23 09:13:25
オリジナル
1507 人が閲覧しました

Spring 3.1 以降、Spring は抽象キャッシュを導入しました。これは、メソッドに @Cacheable などのタグを追加することで、メソッドから返されたデータをキャッシュできます。しかし、それはどのように実装されるのでしょうか?例を見てみましょう。まず @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>();
  }
  
  /**
   * 所有标注了@Cacheable标签的方法切入点
   */
  @Pointcut("execution(@MyCacheable * *.*(..))")
  @SuppressWarnings("unused")
  private void cache() {
  }
  
  @Around("cache()")
  public Object aroundCachedMethods(ProceedingJoinPoint thisJoinPoint)
      throws Throwable {
    logger.debug("Execution of Cacheable method catched");
    //产生缓存数据的key值,像是这个样子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("(");
    //循环出cacheable方法的参数
    for (final Object arg : thisJoinPoint.getArgs()) {
      //增加参数的类型和值
      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 &#39;" + result + "&#39; to cache");
      cache.put(key, result);
    } else {
      logger.debug("Result &#39;" + result + "&#39; was found in cache");
      
    return result;
  }
  
}
ログイン後にコピー

上記のコードは、MyCacheable カスタム タグを処理する方法と、デフォルトでキー値を生成するためのルールを示しています。最終的に生成されるキー値は、おそらく次のようになります: caching.aspectj.Calculator.sum(Integer=1;Integer=2;)

以下のコードは、メソッドに MyCacheable タグを追加します

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 {
      //假设这是代价非常高的计算
      Thread.sleep(3000);
    } catch (InterruptedException e) {
      logger.error("Something went wrong...", e);
    }
    return a + b;
  }
}
ログイン後にコピー

メソッドに追加する With MyCacheable タグでは、キー値が同じ場合、データはキャッシュから直接フェッチされます。同じキー値がない場合は、これは単なる合計演算であるため、再計算されます。これには非常に時間がかかります。時間。ここで 3 秒間スリープさせます。

spring-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>
ログイン後にコピー

テストクラス:

package caching.springaop;
  
import org.apache.log4j.Logger;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
  
/**
 * 使用SpringAOP缓存的简单例子
 * @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");
    //计算出来的结果将会被存储在cache
    logger.info("1 + 2 = " + calc.sum(1, 2));
    //从缓存中获取结果
    logger.info("1 + 2 = " + calc.sum(1, 2));
    logger.debug("Finished!");
  }
  
}
ログイン後にコピー

操作の結果を見てみましょう:

Java 開発フレームワーク Spring はカスタム キャッシュ タグを実装します

結果から、 1 回目は直接計算結果を取得し、2 回目はキャッシュから取得します。

上記は、春のカスタム キャッシュ タグの実装に関するすべての内容です。皆様の学習に役立つことを願っています。

Java 開発フレームワークでの春のカスタム キャッシュ タグの実装に関連するその他の記事については、注目してください。 PHP中国語ウェブサイトです!

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート
私たちについて 免責事項 Sitemap
PHP中国語ウェブサイト:福祉オンライン PHP トレーニング,PHP 学習者の迅速な成長を支援します!