2

実行可能なクラスを自動配線しようとして、別の呼び出しでその別のインスタンスを作成し、それを配列に保持しているときに、この問題に直面しました。

xml 構成は次のとおりです。

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

私のコードでは、次のようなことを試みています。

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();
      }
}   

}

ABCであるクラスにしましょうThread/Runnable/Callable

このように、投げjava.lang.IllegalThreadStateExceptionます。しかし、私が使用する場合、それはうまく動作しますABC tName =appContext.getBean("threadName",ABC.class);

なぜそれが起こるのですか?

getMethod からオブジェクトを取得しようとすると、新しいインスタンスが取得されませんか?

4

2 に答える 2

7

Runnable/Callable を作成し、それを applicationContext に注入する必要がある場合は、ルックアップ メソッドと呼ばれるより良い方法があります。

Runnable/Callable クラスはすべて @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>

次に、抽象クラスであり、1 つの抽象メソッドを持つ TaskFactory 自体を実装しましょう。

@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() メソッドを呼び出すたびに。プロトタイプ オブジェクトの完全に新しいインスタンスを受け取ります。

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

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

注釈を正しく有効にします。

それが役に立てば幸い。

于 2012-04-27T21:42:25.057 に答える
1

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

get メソッドをオーバーライドし、メソッド インジェクションを使用して「getBean」に置き換えるように Spring に指示し、Spring の依存関係を Bean から取得できます。

<bean id="threadHandler" class="com.stackexchange.ThreadHandler">
<lookup-method name="getThreadName" bean="threadName"/>
</bean>
于 2012-04-27T21:28:20.620 に答える