我们的代码库中有一个处理程序类的层次结构,它实现了一种责任链原则。有一个抽象父类,它由多个子类扩展,这些子类也在其构造函数中接收抽象
public abstract class AbstractHandler {
public AbstractHandler(final AbstractHandler next, final PropertyName propertyName) {
this.next = next;
this.propertyName = propertyName;
}
...
public class OneConcreteChildHandler extends AbstractHandler {
public OneConcreteChildHandler(final AbstractHandler next) {
super(next, PropertyName.OneConcreteChild);
}
...
我们现在需要将具体子类之一的实例注入(inject)到新实现的服务类中,并且我们应该在 XML 中进行配置。我们可以为抽象父类配置一个抽象bean,但是这个抽象bean似乎不允许用作具体子bean的构造函数参数
<bean id="abstractHandler" abstract="true" class="...AbstractHandler" />
<bean id="oneConcreteChildHandler" class="...OneConcreteChildHandler" parent="abstractHandler">
<constructor-arg ref="abstractHandler"/> //"abstract bean can not be used here"
</bean>
<bean id="someService" class="...SomeService">
<constructor-arg ref="oneConcreteChildHandler"/>
...
有什么办法可以克服这个问题吗?处理程序类层次结构是遗留代码,我们目前无法修改它们的源代码。
最佳答案
这里的主要问题是您试图注入(inject)一个抽象 bean。你不应该这样做。这个abstractHandler
应该仅用于映射子bean中的parent
。尽管如此,它看起来并不是您真正想要/需要的。您不会在此构造函数中传递抽象对象,而是传递另一个子类的对象。您的链必须有一个终点,构造函数的参数 next
将为 null,如下所示:
<bean id="abstractHandler" abstract="true" class="...AbstractHandler" />
<bean id="oneConcreteChildHandler" class="...OneConcreteChildHandler" parent="abstractHandler">
<constructor-arg ref="twoConcreteChildHandler"/>
</bean>
<bean id="twoConcreteChildHandler" class=".." parent="abstractHandler">
<constructor-arg name="next">
<null />
</constructor-arg>
</bean>
<bean id="someService" class="...SomeService">
<constructor-arg ref="oneConcreteChildHandler"/>
...
关于java - 使用抽象 Spring bean 作为构造函数参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43740132/