如何@Autowire隐藏在ProxyFactoryBean后面的bean?

min*_*das 2 java spring javabeans autowired interceptor

假设我们有两个bean,在Spring中定义

<bean class="foo.A"/>
<bean class="foo.B"/>
Run Code Online (Sandbox Code Playgroud)
public class A {
   @Autowired
   private B b;
}

public class B {
   public void foo() {
      ...
   }
}
Run Code Online (Sandbox Code Playgroud)

我想要实现的是截取所有调用B.foo().看一下文档,我写了拦截器C并改变了bean的定义B如下:

public class C implements org.springframework.aop.MethodBeforeAdvice {
    public void before(final Method method, final Object[] args, final Object target) {
        // interception logic goes here
    }
}
Run Code Online (Sandbox Code Playgroud)
<bean class="foo.C"/>

<bean class="org.springframework.aop.framework.ProxyFactoryBean" scope="prototype">
    <property name="proxyTargetClass" value="true"/>
    <property name="singleton" value="false"/>
    <property name="target">
        <bean class="foo.B" scope="prototype"/>
    </property>
    <property name="interceptorNames">
        <list>
            <value>foo.C</value>
        </list>
    </property>
</bean>
Run Code Online (Sandbox Code Playgroud)

问题:启动时,Spring容器会抱怨:找不到类型为[foo.B]的匹配bean依赖:预计至少有一个bean可以作为此依赖项的autowire候选者.换句话说,它不能注入BA,因为B背后隐藏的org.springframework.aop.framework.ProxyFactoryBean不再"自动地"的认可.如果我将定义替换为简单class=foo.B,容器就可以了.解决这个问题的最佳方法是什么?

奖金问题:是否有可能在B.foo()没有参与ProxyFactoryBean和仅使用注释的情况下实施拦截(最好不参与<aop:...)?

Tar*_*log 5

foo.B(例如foo.BInterface)定义一个接口并foo.BInterface在A类中使用.

还要注意Autowired注射只进行一次.因此,如果foo.A是singleton,它将只接收第一个创建的实例foo.B,而您希望它是原型.

回答奖金:是的,但可能更复杂.作为可能的解决方案,您可以实施BeanPostProcessor.在实现中,您可以使用动态代理替换foo.B. 所以基本上你也这样做,但不是使用<aop:你自己使用基本的Spring功能.再说一遍:你没有解决"原型不是自动装配"的问题,你还需要一个界面.