以更简洁的方式获取一个原型(prototype)性质的自动装配字段的新实例。

12 浏览
0 Comments

以更简洁的方式获取一个原型(prototype)性质的自动装配字段的新实例。

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

XML配置如下:


在我的代码中,我尝试做如下操作:

public class ThreadHandler{
@Autowired
private ABC threadName;
//getter
ABC getThreadName(){
     return threadName;
}
public void someFunction(){
     List abc = new ArrayList(ABC>();
     for (int i=0;i

}

假设ABC是一个Thread/Runnable/Callable类。

以这种方式做会抛出java.lang.IllegalThreadStateException异常。

但是,如果我使用ABC tName = appContext.getBean("threadName",ABC.class);,它可以正常工作。

为什么会出现这种情况?

在调用getMethod方法时,难道我们不会得到一个新的实例吗?

0
0 Comments

在使用Spring框架时,如果我们想要获取一个原型(Prototype)作用域的Bean的新实例,直接访问持有该Bean引用的字段是不会得到新对象的。Spring没有提供任何方法来仅通过字段访问来替换实例级别的引用,它只是通过自动装配设置一次引用,然后一直引用同一个对象。如果我们想要创建一个新的实例,我们需要使用getBean方法。

不过,我们可以使用方法注入来告诉Spring覆盖我们的get方法,并使用'getBean'方法来获取Spring的依赖项,以将Spring依赖从我们的Bean中分离出来。具体做法是使用lookup-method元素来覆盖get方法,如下所示:

<bean id="threadHandler" class="com.stackexchange.ThreadHandler">
<lookup-method name="getThreadName" bean="threadName"/>
</bean>

这样做的目的是让Spring在调用getter方法时生成一个新的Bean实例。

是的,这个方法是有效的,也是我观察到的。但是,除了调用appContext.getBean("name",class)方法之外,是否有更简洁的方法呢?或者说这是唯一可能的方式吗?

是的,你可以使用方法注入来让Spring在调用getter方法时生成Bean实例。这样可以避免直接调用getBean方法,使代码更加简洁。

0
0 Comments

在这个问题中,出现的原因是需要获取一个原型作用域的自动装配字段的新实例,解决方法是使用查找方法(look up method)。

首先,考虑所有的Runnable/Callable类都是原型作用域:

@Scope(value="prototype")
public class Task implements Runnable {
    public void run(){
        .....
    }
}

然后,需要创建一个查找方法工厂(Look up method factory):


    

接着,实现TaskFactory,它是一个抽象类,有一个抽象方法:

@Component(value="taskFactory")
public abstract class TaskFactory {
    public abstract Task createTask();
}

最后,在ThreadHandler中使用TaskFactory获取新的Task实例:

public class ThreadHandler{
    @Autowired
    private TaskFactory taskFactory;
    
    public void someFunction(){
        Runnable task = taskFactory.createTask();
        taskExecutor.execute(task);
    }
}

每次调用taskFactory的createTask()方法时,都会获得一个完全新的原型对象的实例。

需要注意的是,在配置文件中添加以下内容来正确启用注解:



希望这对你有所帮助。

0