0

Facadeレイヤー、Serviceレイヤー、Daoレイヤーを備えたRESTful Webサービスを用意してください。注釈 @Log でマークされた、クラスのすべてのメソッドのすべての呼び出しをジャーナル化しようとしています

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Log {
}

アスペクトコードは次のとおりです。

public class LoggingAspect {
  @Around("@target(Log)")
  public Object log(ProceedingJoinPoint pjp) throws Throwable {
    log.debug("Start " + pjp.getSignature().getName());
    Object result = pjp.proceed();
    log.debug("End " + pjp.getSignature().getName());
    return result;
  }
}

Facade、Service、および Dao は @Log でマークされます。いくつかの例:

public Obj Facade.createObj(String name){ //1
  return service.createObj(name);
}

public Obj Service.createObj(String name){ //2
  return dao.createObj(name);
}

public Obj Dao.createObj(String name){ //3
  Long idOfCreatedObj = /*code that creates an object and returns it's ID*/;
  return loadObjById(idOfCreatedObj); /* load the created object by id */
}

public Obj Dao.loadObjById(Long id){ //4
  return /* code that loads the object by it's id */;
}

この例では、メソッド 1、2、3 が正常にログに記録されています。ただし、ネストされた dao メソッド (loadObjById) はログに記録されません。

なぜ?

PS spring-config.xml には <aop:aspectj-autoproxy proxy-target-class="true"/>

4

1 に答える 1

2

問題は、自己呼び出し ( this.methodcall()) が、Spring によって作成された動的/cglib プロキシをバイパスして、横断的な問題を処理することです。

修正は、完全な Aspectj を使用するか (コンパイル時またはロード時のウィービング)、プロキシを取得して呼び出しを行うことです (alling の代わりにthis.methodCall()proxy.methodCall()

次の方法でプロキシを取得できます。

<aop:aspectj-autoproxy expose-proxy="true"/>

そしてあなたのコードでは: AopContext.currentProxy()はプロキシへの参照を提供します。興味がある場合は、これに関するブログ記事を 1 つ紹介します。

于 2012-10-31T12:44:48.893 に答える