更清洁的方式来获得原型的自动装配字段的新实例 [英] Cleaner way to get new instance of an autowired field that is prototype in nature

查看:195
本文介绍了更清洁的方式来获得原型的自动装配字段的新实例的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遇到了这个问题,同时尝试自动装配一个可运行的类并在不同的调用中创建它的不同实例并将其保存在一个数组中。



xml配置是:

 < bean name =threadNameClass =ABCscope =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 / Callable并将其注入applicationContext时,有更好的做法,它被称为查找方法:



<让我们考虑所有Runnable / Callable类都是@Prototype和@Lazy

  @Component(value =tas k)
@Scope(value =prototype)
@Lazy(value = true)
公共类任务实现Runnable {

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

}

现在你需要创建查找方法工厂:

 < bean id =taskFactoryclass =xyzTaskFactory > 
< lookup-method name =createTaskbean =task/>
< / bean>

现在让我们实现TaskFactory本身,它是抽象类并且有一个抽象方法:

  @Component(value =taskFactory)
公共抽象类TaskFactory {

public abstract Task createTask() ;

}

这就是魔术:

 公共类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>

正确启用注释。



希望它有助于。


I faced this issue, while trying to autowire a runnable class and creating different instances of it in different call and keeping it in an array.

xml configuration is :

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

In my code, I am trying something like this:

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

}

Let ABC be a class which is Thread/Runnable/Callable.

In this way, it throws java.lang.IllegalThreadStateException. But, it works fine, if I use ABC tName =appContext.getBean("threadName",ABC.class);

Why does it happen?

Don't we get a new instance while trying to get an object from getMethod?

解决方案

There is much better practice when you need to create Runnable/Callable and inject it into applicationContext it's called look up method:

Let's consider that all Runnable/Callable classes are @Prototype and @Lazy

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

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

}

Now you need to Create Look up method factory:

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

Now let's implement TaskFactory itself which is abstract class and have one abstract method :

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

    public abstract Task createTask();

}

Here comes the magic:

public class ThreadHandler{

@Autowired
private TaskFactory taskFactory;


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

Every time you are calling createTask() method of taskFactory singleton object. you will receive completely new instance of your prototype object.

P.S: don't forget to add

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

to enable Annotations correctly.

hope it Helps.

这篇关于更清洁的方式来获得原型的自动装配字段的新实例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆