2011-12-07 4 views
7
private final ExecutorService executorParsers = Executors.newFixedThreadPool(10); 

public void parse(List<MyObjInt> objs) { 
    //... bunch of elided stuff .... 

    CompletionService<AsupParseObj> parserService = new ExecutorCompletionService<AsupParseObj>(executorParsers); 

    for (final AsupStoreObj obj : objs) { 
     parserService.submit(new ParseThread(obj)); 
    } 
} 

私は "ParseThread"をDIにしたいと思いますが、プロトタイプのスコープ付きbeanにgetBeanを埋め込むよりも確実にこれを行うより良い方法が必要です。 ...ここでSpringでこれをリファクタリングする最良の方法は?

+0

スプリングDIでは、オブジェクトをPOJOのようにする必要があります。だからこそ、あなたのコードをどこに置くことができるか、私はある種の考え方をすることができるいくつかの方法があります。あなたがしようとしているものに対して、より大きなスニペットといくつかの追加のコンテキストを提供できますか? –

+1

あなたのParseThreadはAsupStoreObject以外の他の依存関係を持っていないようです...この場合は...あなたは春に何をしたいですか? – Dapeng

+1

私の意図は、ParseThread呼び出し可能コードを挿入できるように、このコードをParseThreadの特定の実装に結びつけるのではなく、それらを束縛するのではなく、より簡単に切り替えることでした。 – user1085751

答えて

7

は(3.4.6.1 Lookup method injectionを参照)lookup-methodを使用して完全な構成です:

<bean id="executorParsers" class="java.util.concurrent.Executors" 
     factory-method="newFixedThreadPool" 
     destroy-method="shutdownNow"> 
    <constructor-arg value="10"/> 
</bean> 

<bean id="parserService" class="java.util.concurrent.CompletionService"> 
    <constructor-arg ref="executorParsers"/> 
</bean> 

<bean id="foo" class="Foo"> 
    <lookup-method name="createThread" bean="parseThread"/> 
</bean> 

<bean id="parseThread" class="ParseThread" scope="prototype" lazy-init="true"/> 

とJavaコード:

abstract class Foo { 

    @Autowired 
    CompletionService parserService; 

    protected abstract ParseThread createThread(); 

    public void parse(List<MyObjInt> objs) { 
     for (final AsupStoreObj obj : objs) { 
      ParseThread t = createThread(); 
      t.setObject(obj); 
      parserService.submit(t); 
     } 
    } 
} 

残念ながら、lookup-methodにパラメータを渡すことはできません(SPR-7431と私の記事Creating prototype Spring beans on demand using lookup-methodを参照)。したがって、人工的なsetObject()の必要性があります。

abstractのメソッド/クラスが嫌いな場合、ルックアップメソッドは抽象的なノーオペレーションメソッドであるか、デフォルトの実装で例外をスローすることができます。 Springは実行時に実装をオーバーライドし、効果的にgetBean()を呼び出します。

ボーナス:Executor/CompletionServiceをSpring管理Beanにも翻訳しました。 Springはこれらのアウト・オブ・ザザボックスをサポートしていることに注意してください:Task Execution and Scheduling

+0

Springバージョン3.0.5では、 CompletionServiceはインタフェースであるため、java.util.concurrent.CompletionServiceからjava.util.concurrent.ExecutorCompletionServiceに変更されるため、インスタンス化はあいまいさのために成功できませんでした。 –

0

ここで春があなたに買えるとは思いますが、私はRunnable/Callableのものを吐き出す何らかの種類の工場を投入します。

private final ExecutorService executorParsers = Executors.newFixedThreadPool(10); 

@Autowired 
private CallableFactory myCallableFactory = new MyCallableFactory(); //create this factory 

public void parse(List<MyObjInt> objs) { 
    //... bunch of elided stuff .... 

    CompletionService<AsupParseObj> parserService = new ExecutorCompletionService<AsupParseObj>(executorParsers); 

    for (final AsupStoreObj obj : objs) { 
     parserService.submit(myCallableFactory.createCallable(obj)); 
    } 
} 

また、ExecutorServiceにもSpringを注入できます。