2012-04-27 50 views
2

我試圖自動裝載可運行的類並在不同的調用中創建不同的實例並將其保存在數組中時遇到此問題。更清晰的方式來獲取自然形式的自動佈線字段的新實例

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獲取一個對象時,我們不能獲得新的實例嗎?

+0

你不需要任何吸氣劑。只是用這個。threadName.someFinction();你的意思是 – 2012-04-27 21:25:09

+0

,this.threadName會一直給新的實例?就像appContext.getBean(「name」,class)一樣? – instanceOfObject 2012-04-27 21:28:16

回答

6

有很多更好的做法,當您需要創建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); 
     } 
} 

每次調用taskFactory單例對象的createTask()方法時。您將收到您原型對象的全新實例

P.S:不要忘了添加

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

正確啓用註解。

希望它有助於。

1

不,你沒有得到一個新的對象,只是通過訪問一個字段來保存對作爲Prototype作用域的bean的引用。 Spring沒有任何方法可以將實例級別引用替換爲僅基於字段訪問的新引用。它由自動裝配設置一次,然後它只是一個對象的引用。如果你想要它實際創建一個新的,你需要使用getBean,如你所觀察。

你可以告訴Spring來重寫你的get方法,並用「的getBean」使用方法注入取代它,以獲得對Spring的依賴了你的bean:

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

是的,有道理,這也是我觀察到的。但是有沒有比調用appContext.getBean(「name」,class)更簡潔的方法?或者這是唯一可能的方法? – instanceOfObject 2012-04-27 21:30:29

+0

是的,您可以使用方法注入讓Spring根據getter生成bean: – Affe 2012-04-27 21:32:33

相關問題