0

我们在我们的代码库中有一系列处理程序类,它们实现了一种责任链原则。有一个抽象父类,它是由几个子类,这也收到了抽象在其构造扩展使用抽象Spring bean作为构造函数-arg

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); 
    } 
    ... 

现在,我们需要注入的具体子类的一个实例到一个新实现的服务类,我们应该用XML配置它。我们可以配置抽象父类的抽象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"/> 
    ... 

有什么办法来克服这个?处理程序类层次结构是遗留代码,我们现在无法修改它们的源代码。

回答

2

这里的主要问题是您正在尝试注入一个抽象bean。你不应该这样做。这个abstractHandler应该只用于映射子bean中的parent。尽管如此,它并不是你想要的或需要的。您不会在此构造函数中传递抽象对象,而会传递另一个子类的对象。您链必须有一个终点,在构造函数的参数next将是无效的那样:

<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"/> 
    ... 
+1

谢谢。我们只注意到,在具体的子类中,实际上存在一个用于关闭CoR链(它的构造函数包含super(null,null))的现有的TailChildHandler类,我们可以在配置中使用它,方法与您的twoConcreteChildHandler相同例。这解决了这个问题。 – hammerfest

0

Spring的抽象bean的概念是不一样的Java的抽象类的概念。

在Java中,您不能实例化抽象类的实例,因此尝试将抽象bean映射为抽象java类型在实例化时不起作用。

我会建议你,看看如何Servlet Filters工作(通过FilterChain),或Spring's HandlerInterceptor pattern