1

ServiceFactoryBeanで作成された(ServiceLoaderでロードされた)Beanにアスペクトを適用する際に問題が発生しました。

私の春のコンテキストは次のようになります。

...
<aop:aspectj-autoproxy/>

<bean id="myBean"
      class="org.springframework.beans.factory.serviceloader.ServiceFactoryBean"
      p:serviceType="com.test.MyInterface"/>

<bean id="myAnotherBean"
      class="com.test.MyAnotherBean"/>

私の側面は次のように定義されています。

@Aspect
public class MyAspect {

    @Pointcut("bean(myBean)")
    public void foo() {
    }

    @Pointcut("bean(myAnotherBean)")
    public void bar() {
    }

    @Around("foo()")
    public Object doFoo(final ProceedingJoinPoint jp) throws Throwable {
        return timed(jp, "foo");
    }

    @Around("bar()")
    public Object doBar(final ProceedingJoinPoint jp) throws Throwable {
        return timed(jp, "bar");
    }

    private ThreadLocal<StopWatch> stopWatch = new ThreadLocal<StopWatch>();

    private Object timed(final ProceedingJoinPoint jp, final String taskName) throws Throwable {
        stopWatch.get().add(taskName);
        try {
            return jp.proceed();
        } finally {
            if (stopWatch.get() != null) {
                stopWatch.get().stop(taskName);
            }
        }
    }
}

何らかの理由で、アスペクトはmyAnotherBeanの呼び出しにのみ適用され、myBeanの呼び出しには適用されません。何か案は ?

4

1 に答える 1

0

質問へのコメントで smp7d が示唆しているように、Spring によって作成されたプロキシは、メソッド呼び出しが別のオブジェクトからのものである場合にのみ、アドバイスを適用できます。自己呼び出しは、アドバイスをトリガーするのに十分ではありません。

http://static.springsource.org/spring/docs/3.0.0.M3/spring-framework-reference/html/ch08s06.html

public class Main {

   public static void main(String[] args) {

      ProxyFactory factory = new ProxyFactory(new SimplePojo());
      factory.addInterface(Pojo.class);
      factory.addAdvice(new RetryAdvice());

      Pojo pojo = (Pojo) factory.getProxy();

      // this is a method call on the proxy!
      pojo.foo();
   }
}

ここで理解しておくべき重要なことは、Main クラスの main(..) 内のクライアント コードにプロキシへの参照があることです。これは、そのオブジェクト参照でのメソッド呼び出しがプロキシでの呼び出しになることを意味し、プロキシはその特定のメソッド呼び出しに関連するすべてのインターセプター (アドバイス) に委任できるようになります。ただし、呼び出しが最終的にターゲット オブジェクト (この場合は SimplePojo 参照) に到達すると、 this.bar() や this.foo() など、それ自体で行われる可能性のあるメソッド呼び出しは、この参照であり、プロキシではありません。これには重要な意味があります。これは、自己呼び出しによって、メソッド呼び出しに関連付けられたアドバイスが実行される可能性がないことを意味します。

于 2011-12-06T17:27:37.547 に答える