2017-01-03 16 views
1

使用春@Lazyと@PostConstruct注釈

@Repository 
class A { 

    public void method1() { 
     ... 
    } 
} 

@Component 
class B implements C { 

    @Autowired 
    @Lazy 
    private A a; 

    public void method2() { 
     a.method1(); 
    } 
} 

@Component 
class D { 

    @Autowired 
    private List<C> c; 

    @PostConstruct 
    public void method3() { 
     // iterate on list c and call method2() 
    } 
} 

はのは、春には、次のように豆を初期化するとしましょう:
1.最初のBean Bが作成されます。 Bean Bを作成しているときは、フィールドa@Lazyアノテーションのために初期化されません。
2.次のBean Dが作成されます。それでmethod3()@PostConstructとマークされて実行されますが、Bean AはまだSpringによって触れられていません。したがって、a.method1()が呼び出されると、SpringはBean Aを作成してフィールドaに注入するか、NullPointerExceptionを投げますか?

+2

同じ設定を実行しようとしましたか? – Arpit

+0

@Arpitはい私はそれをして、AをAに注入しました。しかし、SpringがAかDに最初に来るかどうかを保証することはできません.Aが最初に来たら、method3()を実行している間にAを注入することができます。最初にDに来ると、問題が発生する可能性があります。 – rohanagarwal

答えて

4

注入の一部として@Lazyを指定しているときに何が起こっているのかを理解する必要があります。 documentationによれば:

コンポーネントの初期化のためにその役割に加えて、@Lazy 注釈も @Autowired又は@Inject付い注入点上に配置することができます。これに関連して、それは遅い解決プロキシの の注入につながります。

これは、開始時にSpringがクラスAのインスタンスの代わりにプロキシクラスのインスタンスを挿入することを意味します。プロキシクラスは、クラスAと同じインタフェースを持つクラスを自動的に生成します。メソッドプロキシの最初の呼び出しで、クラスAのインスタンスがselfの内部に作成されます。その後、メソッドの呼び出しはすべて、プロキシ内部のクラスAのこのインスタンスにリダイレクトされます。

問題を恐れる理由はありません。

+1

私はこれをテストしました。 NPEがスローされず、最初の呼び出しで(Aのインスタンス)が作成されることを確認しました。 プロキシは、別のオブジェクトの代理オブジェクトまたはプレースホルダで、そのオブジェクトへのアクセスを制御します。プロキシはオブジェクトの呼び出し元と実際のオブジェクト自体の間に位置するため、実際の(またはターゲット)オブジェクトが呼び出されないようにするか、ターゲットオブジェクトが呼び出される前に何かを行うことを決定できます。 – rohanagarwal