Spring方面未应用于ServiceFactoryBean创建的bean

时间:2011-12-06 15:52:05

标签: spring aop serviceloader

我在向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的调用。 有什么想法吗?

1 个答案:

答案 0 :(得分: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(),将被调用这个引用,而不是代理。这具有重要意义。这意味着自我调用不会导致与方法调用相关的建议有机会执行。