鉴于以下类别:
package com.acme;
public class Foo {
private Bar bar;
public void setBar(Bar newBar) {
this.bar = newBar;
}
}
@AcmeService
public interface Bar {}
和一个Spring配置文件:
<beans>
<bean id="foo" class="com.acme.Foo">
<property name="bar" ref="bar" />
</bean>
</beans>
当Spring的配置阶段运行时,是否可以执行以下操作?
我最初被 BeanPostProcessor 和 BeanFactoryPostProcessor 作为实现此目的的手段,尽管在阅读时文档我没有看到一种明显的方式来做我想要的。
如果你想知道,我想要的基础用例是:
除了整个“动态生成代理”位之外,我所有的工作都有效。目前我在我的上下文文件中定义了我的服务接口的空实现,因此它们可以被注入和建议 - 但我宁愿没有生成和签入这么多空接口类。最后,我假设我需要生成这些代理,因为我不知道如何建议对null依赖的尝试调用。
答案 0 :(得分:2)
好的,这里有很多东西要谈。
首先,我认为你不能完全按照你的要求去做。特别是,如果你有<property name="bar" ref="bar"/>
并且bar
没有bean定义,bean初始化将失败,我认为你不能轻易拦截它。当然,您可以编写自己的BeanFactory
本身的子类,但这不是一件容易接受的事情。
与您要求的最接近的现有机制是自动布线。看看AutowiredAnnotationBeanPostProcessor。您可以使用它作为编写自己的BeanPostProcessor
的指南,它会查看容器实例化的每个bean,查找属性的属性,而这些属性又具有@AcmeService
注释。当它找到一个时,它可以生成该类型的代理并注入它。
这将我们带到代理生成本身。寻找的地方是ProxyFactory。这允许您在运行时生成实现任何接口或扩展任何类的对象,同时附加顾问程序/拦截器。这些拦截器可以完成所有工作 - 如果你不想,代理不必有任何“背后”的东西。
使用这种方法,您不需要在配置中使用“挂起”<property name="bar" ref="bar"/>
条目 - Foo
中属性的存在就足以触发该过程。