更清洁的方式来获得原型的自动装配字段的新实例

ins*_*ect 2 java spring autowired illegalstateexception

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

xml配置是:

<bean name="threadName" Class="ABC" scope="prototype" />
Run Code Online (Sandbox Code Playgroud)

在我的代码中,我正在尝试这样的事情:

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();
      }
}   
Run Code Online (Sandbox Code Playgroud)

}

让我们ABC成为一个班级Thread/Runnable/Callable.

通过这种方式,它会抛出java.lang.IllegalThreadStateException.但是,如果我使用它,它的工作正常ABC tName =appContext.getBean("threadName",ABC.class);

为什么会这样?

在尝试从getMethod获取对象时,我们不会获得新实例吗?

dan*_*nik 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(){
.....
}

}
Run Code Online (Sandbox Code Playgroud)

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

    <bean id="taskFactory" class="x.y.z.TaskFactory">
<lookup-method name="createTask" bean="task"/>
</bean>
Run Code Online (Sandbox Code Playgroud)

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

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

    public abstract Task createTask();

}
Run Code Online (Sandbox Code Playgroud)

魔术来了:

public class ThreadHandler{

@Autowired
private TaskFactory taskFactory;


public void someFunction(){
          Runnable task = taskFactory.createTask();
          taskExecutor.execute(task);
      }
}   
Run Code Online (Sandbox Code Playgroud)

每次调用taskFactory singleton对象的createTask()方法时.您将收到原型对象的全新实例.

PS:别忘了添加

<context:annotation-config />
    <context:component-scan base-package="x.y.z"></context:component-scan>
Run Code Online (Sandbox Code Playgroud)

正确启用注释.

希望能帮助到你.