2012-04-27 5 views
2

runnableクラスをautowireし、異なる呼び出しで異なるインスタンスを作成して配列に保持しようとしているときに、この問題に直面しました。本質的にプロトタイプのautowiredフィールドの新しいインスタンスを取得するためのより洗練された方法

XML設定は次のとおりです。

public class ThreadHandler{ 


@Autowired 
private ABC threadName; 

//getter 
ABC getThreadName(){ 
    return threadName; 
} 

public void someFunction(){ 
    List<ABC> abc = new ArrayList(ABC>(); 
    for (int i=0;i<SOME_CONST;i++){ 
      ABC tName = getThreadName(); 
      abc.add(tName); 
      tName.start(); 
     } 
} 

}

ABCThread/Runnable/Callableあるクラスでみましょう:私のコードで

<bean name="threadName" Class="ABC" scope="prototype" /> 

、私はこのような何かをしようとしています。

このようにして、java.lang.IllegalThreadStateExceptionをスローします。 しかし、使用すると正常に動作しますABC tName =appContext.getBean("threadName",ABC.class);

どうしてですか?

getMethodからオブジェクトを取得する際に新しいインスタンスを取得しないでください。

+0

ゲッターは必要ありません。ちょうどこれを使ってください。threadName.someFinction(); –

+0

あなたは、this.threadNameは常に新しいインスタンスを与えることを意味しますか?ちょうどappContext.getBean( "name"、class)のやり方は? – instanceOfObject

答えて

6

あなたが必要とするより良い練習がありますコーラブル/ Runnableを作成し、それを呼び出してのApplicationContextにそれを注入すると、メソッドを調べる:

はのは、すべてのRunnable /呼び出し可能なクラスがあることを考えてみましょう@Prototypeと@Lazy

@Component(value="task") 
@Scope(value="prototype") 
@Lazy(value=true) 
public class Task implements Runnable { 

public void run(){ 
..... 
} 

} 

は今、あなたはメソッドの工場見上げて作成する必要があります。

<bean id="taskFactory" class="x.y.z.TaskFactory"> 
<lookup-method name="createTask" bean="task"/> 
</bean> 

今度は抽象クラスであるTaskFactory自体を実装し、1つの抽象メソッド持ってみましょう:

@Component(value="taskFactory") 
public abstract class TaskFactory { 

    public abstract Task createTask(); 

} 

をここで魔法が来る:

public class ThreadHandler{ 

@Autowired 
private TaskFactory taskFactory; 


public void someFunction(){ 
      Runnable task = taskFactory.createTask(); 
      taskExecutor.execute(task); 
     } 
} 

taskFactoryシングルトンオブジェクトのcreateTask()メソッドを呼び出すたびに、 プロトタイプオブジェクトの全く新しいインスタンスが届きます。

P.S:正しく注釈を有効にするには、

<context:annotation-config /> 
    <context:component-scan base-package="x.y.z"></context:component-scan> 

を追加することを忘れないでください。

希望します。

1

いいえ、PrototypeとしてスコープされたBeanへの参照を保持するフィールドにアクセスするだけで、新しいオブジェクトを取得することはできません。 Springは、インスタンス参照のみをフィールド参照に基づく新しい参照で置き換える方法はありません。それはautowiringによって一度設定され、それはただ一つのオブジェクトへの参照に過ぎません。実際に新しいものを作成したい場合は、あなたが観察したようにgetBeanを使う必要があります。

あなたは豆のうち、春の依存関係を取得するには、お使いのgetメソッドをオーバーライドして、「getBean」を用いた方法で注入して、それを置き換えるために春を告げることができます。

<bean id="threadHandler" class="com.stackexchange.ThreadHandler"> 
<lookup-method name="getThreadName" bean="threadName"/> 
</bean> 
+0

はい、意味があり、これも私が観察したものです。しかし、appContext.getBean( "name"、class)を呼び出すよりもきれいな方法がありますか?または、これが唯一の方法ですか? – instanceOfObject

+0

はい、メソッド注入を使用すると、getterに応答してBeanを生成することができます。 – Affe

関連する問題