2011-11-14 10 views
6

私はServiceBに依存しているServiceAを持っています。 serviceBは、lazy-init = trueのSpring Beanファイルから来ています。つまり、Beanを要求すると、serviceBを初期化するだけです。Spring DI - すべての依存するBeanを初期化しません。

私はアプリケーション全体でServiceAを使用しています。セッターベースの注入を行うと、ServiceBは初期化されます。

は私がサービスAが ServiceBを必要と呼ばれるサービスAのいずれかの方法まで、ServiceB を初期化しないようにしたいです。これを行う1つの方法は、Aspects を使用していましたが、特にserviceBのspring xmlファイルやserviceBのアノテーション、またはプロキシフラグの中で最も簡単な解決策を探していました。

誰かが助けることができますか?

+0

[春に春の怠惰なプロキシファクトリがありますか?](http://stackoverflow.com/questions/2391168/is-there-a-spring-lazy-proxy-factory-in-spring) – skaffman

+0

ServiceBファクトリをServiceAに渡すのはどうですか? –

答えて

6

私はあなたが必要とするものはLazyInitTargetSourceだと思います。

有用

プロキシ参照が初期化に必要とされるが、実際の対象物は、最初の使用まで初期化されるべきではありません。ターゲットBeanがApplicationContext(またはシングルトンBeanを事前にインスタンシエートするBeanFactory)で定義されている場合は、「lazy-init」としてマークする必要があります。そうでない場合、起動時にApplicationContext(またはBeanFactory)によってインスタンス化されます。

0

私は春については分かりませんが、GuiceではProvider<ServiceB>を使用するので、サービスを利用する準備ができたらprovider.get().callMethodOnB(...)となります。

これはJSR-330仕様の一部なので、春には同等のものがある可能性があります(私はかなりの時間Springの最新バージョンを使用していません)。

+1

今すぐ見る!あなたがdownvoteに行くなら、理由を言ってノートを残すのは丁寧ではないでしょうか? – dty

0

method injectionも使用できます。 原則として、コンテキストからシングルトンBeanの新しいインスタンスを取得する必要がありますが、それもあなたのケースで使用できます。

サンプル:

package org.test.lazy; 

public abstract class ParentBean { 
    public abstract LazyBean getLazy(); 
    public void lazyDoingSomething() { 
     getLazy().doSomething(); 
    } 
} 

package org.test.lazy; 

public class LazyBean { 
    public void init() { 
     System.out.println("Initialized"); 
    } 
    public void doSomething() { 
     System.out.println("Doing something"); 
    } 
} 

package org.test.lazy; 

import org.junit.Test; 
import org.junit.runner.RunWith; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.test.context.ContextConfiguration; 
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 

@ContextConfiguration 
@RunWith(SpringJUnit4ClassRunner.class) 
public class LazyTest { 

    @Autowired 
    private ParentBean parentBean; 

    @Test 
    public void test() { 
     parentBean.lazyDoingSomething(); 
     parentBean.lazyDoingSomething(); 
    } 
} 

<?xml version="1.0" encoding="UTF-8"?> 

<beans xmlns="http://www.springframework.org/schema/beans" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xsi:schemaLocation=" 
    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 
"> 
    <import resource="classpath:org/test/lazy/Lazy-context.xml"/> 
    <bean id="parentBean" class="org.test.lazy.ParentBean"> 
     <lookup-method bean="lazyBean" name="getLazy"/> 
    </bean> 
</beans> 

<?xml version="1.0" encoding="UTF-8"?> 

<beans xmlns="http://www.springframework.org/schema/beans" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xsi:schemaLocation=" 
    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 
" 
default-lazy-init="true"> 

    <bean id="lazyBean" class="org.test.lazy.LazyBean" init-method="init" /> 
</beans> 

怠け者のBeanは、オンデマンドで一度だけ初期化されます。

1

あなたはhttp://static.springsource.org/spring/docs/3.1.x/javadoc-api/org/springframework/aop/framework/autoproxy/target/LazyInitTargetSourceCreator.htmlで議論されているしようとする場合があります別のアプローチ:

は「レイジー初期化」と定義される各Bean ためLazyInitTargetSourceを強制TargetSourceCreator [LazyInitTargetSourceCreatorがあります]。これにより、それぞれのbeanの 用に作成されたプロキシが生成され、実際にターゲットBeanインスタンスを初期化せずにそのようなBeanへの参照を取得できます。 唯一の怠惰な-INITプロキシを作成するための具体的な豆や 用のカスタムインターセプタとの組み合わせで、自動プロキシ クリエーターのためのカスタムTargetSourceCreatorとして登録する

。例えば、 としてXMLアプリケーションコンテキスト 定義でインフラBeanを自動検出:アプリケーション・コンテキストでこの数回やって自分自身を見つける場合は、これは設定に保存されます

<bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator"> 
    <property name="customTargetSourceCreators"> 
    <list> 
     <bean class="org.springframework.aop.framework.autoproxy.target.LazyInitTargetSourceCreator"/> 
    </list> 
    </property> 
</bean> 

<bean id="myLazyInitBean" class="mypackage.MyBeanClass" lazy-init="true"> 
    ... 
</bean> 

関連する問題