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>

现在让我们实现 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

不,您不会得到一个新对象,只是通过访问一个包含对范围为 Prototype 的 bean 的引用的字段。Spring 没有任何方法可以将您的实例级别引用替换为仅基于字段访问的新引用。它由自动装配设置一次,然后它只是对那个对象的引用。如果您希望它实际创建一个新的,您需要按照您观察到的那样使用 getBean。

您可以告诉 Spring 覆盖您的 get 方法并使用方法注入将其替换为“getBean”,以从您的 bean 中获取 Spring 依赖项:

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