5

Spring を使用して、注釈付きの Aspect クラスで依存性注入を行う際にいくつか問題がありました。Spring コンテキストの起動時に CacheService が注入されますが、ウィービングが行われると、cacheService が null であることが示されます。そのため、Spring コンテキストを手動で再検索し、そこから Bean を取得する必要があります。それについて別の方法はありますか?

これが私のアスペクトの例です:

import org.apache.log4j.Logger;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import com.mzgubin.application.cache.CacheService;

@Aspect
public class CachingAdvice {

  private static Logger log = Logger.getLogger(CachingAdvice.class);

  private CacheService cacheService;

  @Around("execution(public *com.mzgubin.application.callMethod(..)) &&"
            + "args(params)")
    public Object addCachingToCreateXMLFromSite(ProceedingJoinPoint pjp, InterestingParams params) throws Throwable {
    log.debug("Weaving a method call to see if we should return something from the cache or create it from scratch by letting control flow move on");

    Object result = null;
    if (getCacheService().objectExists(params))}{
      result = getCacheService().getObject(params);
    } else {
      result = pjp.proceed(pjp.getArgs());
      getCacheService().storeObject(params, result);
    }
    return result;
  }

  public CacheService getCacheService(){
    return cacheService;
  }

  public void setCacheService(CacheService cacheService){
    this.cacheService = cacheService;
  }
}
4

3 に答える 3

4

アスペクトはSpringコンテナの前に作成されるため、アスペクトのファクトリメソッドaspectOf(ExampleClass.class)からアスペクトを取得する必要があります。

Spring XML構成から、次のようにアスペクト(オブジェクト)を取得できます。

<bean id="traceAspect" class="aspects.trace.TraceAspect"
    factory-method="aspectOf" />

ファクトリメソッドは、列挙型のようにSpringコンテナの外部で作成されたオブジェクトを取得する通常の方法です。

于 2010-03-30T20:53:36.670 に答える
3

問題は、私が理解しているように、Spring がこのタイプの Bean を作成していることですが、AspectJ フレームワークもこのタイプのインスタンス化を作成していることです。

AspectJ に Aspect が作成されたことを知らせる Bean をインスタンス化するために使用するファクトリ メソッドを Spring に提供したいと考えています。

<!-- An @Aspect-annotated class -->
<bean id="bar" class="com.foo.bar" factory-method="aspectOf">
    <property name="meaning" value="42" />
</bean>

正当な信用を与えるために、私は今日この質問に出くわし、後で他の場所で答えを見つけたので、ループを閉じるために戻ってきます.

ここで起こっている魔法については明確ではありませんが、このフレーバーのいくつかの静的コンストラクターを提供する Aspects クラスがあることがわかります。おそらく、AspectJ は、この種の構築を容易にするために、同じ名前の静的メソッドを各アスペクトにも織り込んでいます。

于 2009-09-24T22:37:39.723 に答える
2

私もそのような問題に直面しました。

これが修正された方法です:

@Aspect
public class MyAspect {
  @Resource // telling spring that at first look up bean by name;
  Session session; // resource that won't of being setup;

  private static class MyAspectHolder {
    static final MyAspect instance = new MyAspect();
  }

  ...

  // special purpose method w/o it - stuff doesnt work;
  public static MyAspect aspectOf() {
    return MyAspectHolder.instance;
  }
}

そしてもちろん<aop:aspectj-autoproxy />、アスペクト Bean 定義とともに設定を忘れないでください。

于 2010-03-16T18:09:16.130 に答える