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