假设我们有两个在 Spring 中定义的 bean
<bean class="foo.A"/>
<bean class="foo.B"/>
public class A {
@Autowired
private B b;
}
public class B {
public void foo() {
...
}
}
我想要实现的是拦截所有对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
}
}
<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>
问题:启动时,Spring 容器提示:找不到依赖项的 [foo.B] 类型的匹配 bean:预计至少有 1 个有资格作为此依赖项的 Autowiring 候选者的 bean 。换句话说,它无法注入(inject)B
进入A
因为B
隐藏在org.springframework.aop.framework.ProxyFactoryBean后面,并且不再“自动”识别。如果我将定义替换为简单的 class=foo.B
,容器启动正常。解决这个问题的最佳方法是什么?
额外问题:是否可以实现 B.foo()
的拦截没有 ProxyFactoryBean
的参与并且仅使用注释(最好不涉及 <aop:...
)?
最佳答案
定义 foo.B
的接口(interface)(例如 foo.BInterface
)并使用 foo.BInterface
在A类中。
还要注意Autowired
注入(inject)仅进行一次。所以如果 foo.A
是单例的,它只会接收 foo.B
第一个创建的实例,而您希望它成为原型(prototype)。
奖金答案:是的,但可能更复杂。作为一种可能的解决方案,您可以实现 BeanPostProcessor
。在实现中,您可以用动态代理替换 foo.B。所以基本上你做同样的事情,但不是使用 <aop:
您可以使用基本的 Spring 功能自行完成。再说一次:你没有解决“原型(prototype)不是 Autowiring ”的问题,你仍然需要一个接口(interface)。
关于java - 如何@Autowire隐藏在ProxyFactoryBean后面的bean?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6507917/