2014-08-27 27 views
4

我想通過定製的jar提供一個默認的bean。只有當用戶實現一個特定的abstract類時,應該跳過默認的bean注入。如何在條件中提供Spring中的默認bean?

以下設置已正常工作,除了一件事情:default有線類中的任何注入類都是null!我可能會錯過什麼?

@Configration 
public class AppConfig { 
    //use the default service if the user does not provide an own implementation 
    @Bean 
    @Conditional(MissingServiceBean.class) 
    public MyService myService() { 
     return new MyService() {}; 
    } 
} 


@Component 
public abstract class MyService { 
    @Autowired 
    private SomeOtherService other; 

    //default impl of the method, that may be overridden 
    public void run() { 
     System.out.println(other); //null! Why? 
    } 
} 

public class MissingServiceBean implements Condition { 
    @Override 
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { 
     return context.getBeanFactory().getBeansOfType(MyService.class).isEmpty(); 
    } 
} 

MyService bean已創建並且也可以被注入。但包含的類是空的。

如果我刪除@Conditioanl註釋,所有內容都按預期工作。

+0

使用XML配置你可以做到這一點,但這不是你想要的方式嗎? – 2014-08-27 08:36:49

+0

對,我想只有基於註釋的配置。 – membersound 2014-08-27 08:38:49

回答

2

你最簡單的可能性是@Primary標註的使用。你定義你的接口/抽象類並構建一個默認實現。直到這裏,基本的春天autowiring。

現在您使用@Primary創建另一個實現,並使其在應用程序上下文中可用。 Spring現在將選擇自動裝配的主要實現。


在Spring 4.1+另一個possibilty將自動裝配有序List<Intf>和詢問接口與supports(...)調用來獲取你給到supports任何參數當前實現。您將默認實現設置爲low priority,更詳細的設置爲更高優先級。像這樣,你甚至可以建立更詳細的默認行爲。我正在使用這種方法進行多種配置來處理具有默認和特定實現的不同類。

一個例子是在權限評估期間,我們對基類有一個默認配置,對於域類有另一個更高的配置,對於特定域實體有更高的可能。權限評估者遍歷列表並檢查每個實現是否支持該類並委派實現。

我沒有在這裏的代碼,但我可以稍後分享它,如果需要,使更清晰。

+0

我喜歡'優先級'的想法,並會嘗試。但爲什麼這種方法限制在4.1+以上? – membersound 2014-08-27 14:07:08

+1

@membersound。原因在於'Order'接口或註釋的自動裝配列表之前沒有實現,我需要在那時編寫自己的beanfactory。現在直接支持接線有序列表。它已經可以在4.0版本了,但我不確定,這就是爲什麼我寫了4.1+。 – 2014-08-27 15:54:31

0

你的代碼更改爲以下:

public abstract class MyService { 

    private final SomeOtherService other; 

    public MyService(SomeOtherService other) { 
     this.other = other; 
    } 

    //default impl of the method, that may be overridden 
    public void run() { 
     System.out.println(other); 
    } 
} 

@Configration 
public class AppConfig { 

    @Autowired 
    private SomeOtherService other; 

    //use the default service if the user does not provide an own implementation 
    @Bean 
    @Condition(MissingServiceBean.class) 
    public MyService myService() { 
     return new MyService(other) {}; 
    } 
} 
+0

好的,可以工作,但我更喜歡直接在課堂上注射。問題是爲什麼這不與'@ Conditional'註解一起工作。因爲,如果我刪除註釋,內部服務都連線正確。 – membersound 2014-08-27 08:36:09

+0

@membersound我最好的猜測是'Condition'的存在會在內部做某些事情來阻止'AutowiredAnnotationBeanPostProcessor'的工作 – geoand 2014-08-27 08:38:49

+0

@membersound另外''AutowiredAnnotationBeanPostProcessor'有可能在處理'@ Condition'之前運行。你需要深入Spring的內部,看看發生了什麼 – geoand 2014-08-27 08:45:31

相關問題