我面对这个问题,而试图自动装配一个可运行的类,并在不同的呼叫建立它的不同实例并将其保存在一个数组。
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对象不要我们得到了一个新的实例?
还有就是当你需要创建Runnable接口/赎回,注入的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);
}
}
每次您呼叫的CreateTask taskFactory单一对象的()方法。 您将收到您的原型对象的完全新的实例 。
PS:不要忘了添加
<context:annotation-config />
<context:component-scan base-package="x.y.z"></context:component-scan>
正确启用注解。
希望能帮助到你。
不,你没有得到一个新的对象,只是通过访问保存到作用域为原型的bean创建一个参考的字段。 春天没有任何办法,以取代仅基于字段访问一个新的参考您的实例级参考。 它是由自动连接设置一次,然后它只是一个对象的引用。 如果你想让它实际上是创建一个新的,你需要为你观察到使用的getBean。
你可以告诉Spring来重写你的get方法,并用“的getBean”使用方法注入取代它,以获得对Spring的依赖你的豆:
<bean id="threadHandler" class="com.stackexchange.ThreadHandler">
<lookup-method name="getThreadName" bean="threadName"/>
</bean>
文章来源: Cleaner way to get new instance of an autowired field that is prototype in nature