清洁的方式来获得一个自动装配Autowired领域的新实例,它是原型性质(Cleaner way t

2019-06-24 01:09发布

我面对这个问题,而试图自动装配一个可运行的类,并在不同的呼叫建立它的不同实例并将其保存在一个数组。

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对象不要我们得到了一个新的实例?

Answer 1:

还有就是当你需要创建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>

正确启用注解。

希望能帮助到你。



Answer 2:

不,你没有得到一个新的对象,只是通过访问保存到作用域为原型的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