2014-04-04 53 views
1

彈簧4包含重大改進,泛型類型的分辨率,但我有與自動裝配一個泛型類型的麻煩當類型參數是對含有bean類參數。彈簧自動裝配參數化泛型類型

我需要跟蹤提交給外部服務的作業的狀態,並且我希望在每個作業啓動時創建一個條目,並在收到回發時清除或更新它。我通常試圖保持我的持久性策略與服務接口分開,所以我有一個接口JobStatus和一個Spring Data Mongo類MongoJobStatus implements JobStatus。由於外部服務都有機會分配一個ID(例如HTTP 502)前參加工作可能會失敗,我需要通過JobStatus回到服務識別更新:

interface JobStatusService<S extends JobStatus> { 
    S beginJob(...); 
    S updateJobStatus(S targetJob, Status newStatus); 
    void finishJob(S targetJob); 
} 

因此,我處理射擊工作和記錄回發的Spring控制器看起來像這樣;控制器類帶有一個類型參數,這樣我可以存儲新的狀態對象,並將其傳遞迴服務:

@Controller 
public class JobController<JS extends JobStatus> { 
    @Autowired JobStatusService<JS> jobService; 

    ... handler method ... 
    JS status = jobService.createJob(info, goes, here); 
    // submit job via HTTP 
    jobService.updateJobStatus(status, Status.PROCESSING); 
    ... 
} 

我的MongoDB支持的實現看起來是這樣的:

public class MongoJobStatusService implements JobStatusService<MongoJobStatus> { 
    MongoJobStatus beginJob(...) {...} 
    MongoJobStatus updateJobStatus(MongoJobStatus job, Status newStatus) {...} 
} 

當我嘗試要啓動,Spring上下文將以NoSuchBeanDefinitionExceptionJobStatusService失敗。我已經證實,如果我設置required=falseMongoJobStatusService bean已正確組件掃描並安裝在上下文中,但Spring似乎無法理解該類實現了該參數化的通用接口。

有什麼辦法來指定春天,我需要實現與在含有豆級參數,而不是嵌入式的現場級文字類型參數類型參數的通用接口豆?

+0

也許你'MongoJobStatusService '必須實現'JobStatusService',而不是'JobStatus'? –

+0

@ArtemBilan減法中的錯字。謝謝你的收穫。 – chrylis

回答

1

Spring容器似乎無法解析控制器類上的可接受類型參數,但如果明確提供了這些類型參數,它可以解決注入字段。我已經能夠用文字型子類控制器類未達最佳的解決此問題:

@Controller 
public class MongoJobController<MongoJobStatus> {} 

opened a JIRA issue,這和有a minimal example on GitHub

2

嘗試添加:

@Autowired 
@Qualifier("mongoJobStatusService") 
JobStatusService<JS> jobService; 

,並指定MongoJobStatusService bean的名字。

+0

我會嘗試,但我強烈期望它不起作用。問題不在於區分bean,而是Spring根本找不到匹配。 – chrylis

+0

Acalally,即使這個@ @ Autowired \t @Qualifier(「jobService」) \t Object jobService;'works。沒錯,它可能不會按類型找到bean,但可以通過'id'來嘗試。另一方面,如果你的'JobController'真的看到了所需的bean,你可以注入'BeanFactory'並查看調試。 –

+0

因此,放置限定符取代了類型解析約束?我確信將字段類型敲入Object將會使我的服務bean符合條件,但是我會失去所有類型安全性,這是該練習的重點。 – chrylis

1

其實Spring沒有找到匹配的Bean,也許是因爲JobStatusService是高層次的。

儘量把MongoJobStatusService和JobStatusService之間的其它接口,這樣

public class MongoJobStatusService implements IMongoJobStatusService { 
..} 

public interface IMongoJobStatusService implements JobStatusService<MongoJobStatus> { 
... 
} 

I'had同樣的問題(Spring autowire trouble with generic parameter),我解決了它這樣...