2017-07-31 12 views
1

基本クラスXYがあり、複数の実装があります。ただし、パラメータ化された型ごとに実装が1つしかないため、@Autowiredはどのサブクラスが必要であるかを把握できるはずです。抽象汎用クラスのSpring 4依存性注入が機能しない

これは実際には、基本クラスXY(したがってそのすべてのサブクラス)に第2パラメータUを追加する前に機能します。しかし、ここで春の初期化中にエラーがある、と付け加えた後:

org.springframework.beans.factory.UnsatisfiedDependencyException: エラー「て、myApp」名前を持つBeanの作成: はフィールド「X1」を通して表現不満の依存関係を、ネストされた例外は org.springframework.beans.factory.UnsatisfiedDependencyException: 名前 'xImpl1'を持つBeanの作成中にエラーが発生しました:満足していない依存性 フィールド 'y'で表現されました。入れ子になった例外は org.springframework.beans.factory.NoSuchBeanDefinitionException:いいえ タイプ 'test.Y>'の修飾Beanである が利用可能です:予期しないものとして少なくとも1つのbeanは、 の候補となります。依存注釈: {@ org.springframework.beans.factory.annotation.Autowired(必須=真)}

githubの(Mavenプロジェクト)におけるコード:https://github.com/kevincentius/spring-di-abstract-generic-problem/tree/master/spring-test

抽象ジェネリッククラスX<T, U>Y<T, U>相互参照:

@Component 
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) 
public abstract class X<T, U> { 

    protected T t; 
    protected U u; 

    @Autowired 
    protected Y<T, X<T, U>> y; // error when initializing xImpl1 

    // ... 

} 

クラスYは、実装クラスV(例えばXImpl1を)知っています。抽象クラスYのみを認識し、その実装タイプ(例えば、YImpl1)を認識しないXとは対照的に。

@Component 
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) 
public abstract class Y<T, V extends X<T, ?>> { 

    protected T t; 
    protected V v; 

    // ... 

} 

POJOクラス:

public class A { 
    // pojo 
} 

シンプルなインターフェース:

public interface B { 
    // ... 
} 

これは単なるXのサブクラスの一つであるが、これはパラメータ化された型とXの唯一のサブクラスでありますAおよびB(すなわち、X<A, B>の唯一のサブクラス):

@Component 
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) 
public class XImpl1 extends X<A, B> { 
    // ... 
} 

同じように - Y<A, B>の唯一の実装です。パラメータ化された型が異なるYの実装があります。

@Component 
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) 
public class YImpl1 extends Y<A, XImpl1> { 
    // ... 
} 

最後の実装を使用します。

@Component 
public class MyApp { 
    @Autowired 
    XImpl1 x1; // error 
} 

は有用な情報次のようになります。

私はクラスXとYは、非抽象的であることを作る場合は、初期化エラーがその後もなくなっているが、 XImpl1がXのメソッドをオーバーライドする場合、これは依存性注入の後では適用されません!つまりMyAppでは、x1.something()を呼び出すとXImpl1のメソッドが実際に呼び出されるのではなく、Xクラスのsomething()メソッドが呼び出されます。

私はここでいくつかの間違いをしているかもしれませんが、誰かが何かを指摘できれば嬉しいです。しかし、そうでなければ、まだ春のようないくつかの制限があるようですね?

答えて

0

私は春の制限を認識していません。私は簡素化をお勧めします。問題が春であることを前提にしないでください:あなたです。

あなたのデザインは不必要に複雑であると言います。

これが例か実際のコードかどうかはわかりません。ジェネリックの名前と使用は、これを読んで理解することが不可能になります。あなたはこのクラス階層からすべての理解を抽象化しました。

これは、継承よりも合成が優先されるように思えます。それは私の意見です。

コンストラクタが@Autowireの場合は、入力するパラメータを正確に指定してパラメータリストに@Qualifierを追加することをお勧めします。あなたのbean factoryによって管理されている同じタイプのいくつかのbeanがある場合、Springがあなたの心を読むことを期待するのは無理です。オートワイヤリングするものを選択することはできません。 の場合は、しか決定できません。

世界は、オブジェクト指向から離れた関数プログラミングの方向に向かっています。私はlambdasと新しいjava.util.functionパッケージを使用してこれを改善できるかどうかを知りたいと思っています。柔軟性と理解度を高めることができます。

関連する問題