2012-04-24 11 views
1

私は親抽象クラスと具象子クラスを持っています。抽象メソッドには、具体的なメソッドと子クラスが実装する抽象メソッドがあります。これらのクラスは両方ともSpring Beanとして設定されています。Spring:オブジェクトがベースクラスBeanと子クラスBeanの両方に注入された場合、値はnullです。

スプリング構成:コードスニペットは、以下に類似している

<bean id="parent" class="Parent" abstract="true"> 
    <property name="propA" ref="propA"/> 
    <property name="cacheMan" ref="cacheMan"/> 
</bean> 

<bean id="child" class="Child" parent="parent"> 
    <property name="propB" ref="propB"/> 
    <property name="cacheMan" ref="cacheMan"/> 
</bean> 

<!-- Of course, cacheMan is defined elsewhere and not relevant here.--> 

クラス定義:

public abstract class Parent { 
     private A propA; // A is irrelevant. 
     private CacheManager cacheMan; // This is the object in question. 
     public void doProcess1() { 
     //code logic 
     if (cacheMan == null) { 
      // Error! 
     } 
     } 
     public void doProcess2(); 
    } 

    public class Child extend Parent { 
     private B propB; // Again, B is irrelevant. 
     private CacheManager cacheMan; // This is the object in question. 
     public void doProcess2() { 
     //code logic 
     } 
    } 


public class Test { 
     private Parent parent; //Assume this is Spring injected and it's of type Child. 
     public void doTest() { 
      parent.doProcess1(); // Error thrown since cacheMan is null. 
     } 
} 

これらのクラスの両方cacheManに適したゲッター/セッターメソッドを有します。私はdoProcess1()メソッドでcacheManがnullであることを理解していません。しかし、私はその行を変更する場合

cacheMan == nullから、エラーがスローされません。

parentがインスタンスChildであるため、getCacheMan()が子クラスに注入されたオブジェクトを取得していると思うので、nullではありません。

これが明白でない場合は、それを明記してお知らせください。

答えて

2

この問題はSpringではなく、Java言語に関連しています。特定の方法で上書きすることです。

あなたはsetCacheMan()(これは私が前提とする)メソッドで、抽象的な親クラスと子クラスの両方で定義されています。 Springがそのメソッドを呼び出すと、常に子のオーバーライドされたバージョンを呼び出し、そのバージョンは子のcacheManの参照も変更します。親にあるcacheMan参照は、アクセスする唯一のメソッドが子でオーバーライドされているため、実際には触れません。

cacheMan == nullからgetCacheMan() == nullにその行が変更された場合、エラーはスローされません。

すでに言われていることからはっきりしています - getCacheMan()もオーバーライドされています。 cacheMan親の参照はnull(上記参照)ですが、getCacheMan()が上書きされているため、親ではなく子のcacheManにアクセスします。効果的には2つの変数がありますが、子供の変数は変更できません。

ソリューション:親Beanのアイデアが一つの場所に共通の依存関係を持っており、すべての子供にそれらの重複を避けるためである。

<bean id="parent" class="Parent" abstract="true"> 
    <property name="propA" ref="propA"/> 
    <property name="cacheMan" ref="cacheMan"/> 
</bean> 

<bean id="child" class="Child" parent="parent"> 
    <property name="propB" ref="propB"/> 
</bean> 

そして、いずれかの子クラスができるようにcacheMan保護または少なくとも保護されているゲッターを宣言それにアクセスする。子クラスにcacheManフィールドを作成しないでください。

+0

トマース、私はあなたに私が推測した説明を与えていると信じていますが、実際にはそれを得ていません。なぜ、抽象化されたキャッシュマンを単独で保持しないのでしょうか。子クラスがそれをオーバーライドしていることは理解していますが、その問題は「親の代わりに子インスタンスを取得する理由」のようなものでした。私はnullが親のcacheManフィールドに注入される修飾値であるかどうかわかりません。 – asgs

+1

@asgs:それは事です、 'null'はあなたの親に注入されません!私はSpringが 'setCacheMan()'を2回呼び出すと思います.1回は親に対して、もう1回は子に対して、両方の呼び出しで正しい 'cacheMan'参照を提供します。しかし、このメソッドはオーバーライドされているので、子では 'setCacheMan()'が2回呼び出され、親では 'setCacheMan()'は呼び出されません。ここでも、これはSpringとはほとんど関係がありません。これはJavaの仕組みです。 'System.out'を' setCacheMan() 'の両方の実装に追加して、いつ呼び出すかを見てください。私は親のバージョンは決して呼び出されないだろう - そして、親の 'cacheMan'参照は決して更新されないでしょう。 –

+0

私は両方のセッターにSOPを追加しました。子は親に依存しているため、親と子の順番(サーバーの起動中)の両方で実際に両方を呼び出します。それ以降に何が起こるか分からないと、親のcacheManがnullに設定されます。 – asgs

関連する問題