2011-04-07 63 views
5

鑑於我有一個Spring bean配置爲如何通過名字覆蓋春天服務組件,使用註釋只有

@Service("myService") 
public class DefaultService extends MyService { 
} 

和一類使用這個bean

public class Consumer { 
    @Autowired 
    @Qualifier("myService") 
    private MyService service; 
    ... 
} 

現在我想我的項目,那包括前面的類別,以便Consumer另一個實施MyService被注入。因此,我想覆蓋豆myService

@Service("myService") 
public class SpecializedService implements MyService { 
} 

導致Consumer目前正在實施的SpecializedService而不是DefaultService一個實例。根據定義,我不能在Spring容器中擁有兩個同名的bean。我怎麼能告訴春天,新服務的定義應該覆蓋老的?我不想修改Consumer類。

回答

2

要麼定義服務豆明確

<bean id="myService" class="x.y.z.SpecializedService" /> 

或組件的掃描。

無論是哪種情況,在您的應用程序上下文中,都應避免顯式定義DefaultService並避免對其進行組件掃描。

+0

謝謝,威利。我們最終選擇了您的解決方案,因爲我們也出於維護原因(我們正在討論數百個服務)決定將每個服務的列表保留在一個文件中 - 即Spring bean配置。只定義id和classname並不是太痛苦,因爲只使用註釋更具誘惑力。 – 2011-04-07 08:37:05

2

通過,如果有一種方法只用註釋來做到這一點(不是從DefaultService取出@Service註釋等)使用過濾器

<component-scan base-package="your-package"> 
    <exclude-filter type="regex" expression="DefaultService" /> 
</component-scan> 

不知道從組件掃描排除它。

+0

謝謝,威廉,我相信你的解決方案能夠奏效。但之後我必須自己掃描我的服務。好主意! – 2011-04-07 08:34:43

0

基於註釋的接線發生在基於XML的配置之前,這意味着以XML定義的bean將覆蓋由註釋完成的接線。 因此明確地界定它在XML,像威利曾表示將做的工作

<bean id="myService" class="x.y.z.SpecializedService" /> 

春建議使用XML服務和存儲庫豆類和註釋的MVC豆。它還推薦@Autowired,無需掃描組件。但是註釋通常被鼓勵,儘管它將代碼和配置合併在一起(反對關注的分離)。

第二件事是使用@Qualifiers(「聲明的bean的id」)它傳遞的地方。

-2

我知道,它遲到了。仍然張貼它。

對於MyService的不同實現,您應該有不同的名稱。

例如

@Service("mySpecializedService") 
public class SpecializedService implements MyService { 
} 

@Service("myService") 
public class DefaultService extends MyService { 
} 

雖然自動裝配他們(說在控制器),你可以使用@Qualifier下文所述注入所需的實現。

要獲得默認實現

@Autowired 
@Qualifier("myService") 
MyService myService; 

要獲得專門的實現

@Autowired 
@Qualifier("mySpecializedService") 
MyService myService; 
+0

這與OP要求的完全相反。 – 2017-09-21 03:18:44

+0

@HimanshuBhardwaj ..你可以分享你的方法..? – user6087330 2017-09-23 08:34:37

+0

我將在另一個配置文件(xml或java)中定義新的bean,並讓它覆蓋前一個,或者將繼續使用Spring Profiles或@Conditional。 – 2017-09-25 05:51:03