2015-11-24 37 views
2

我有一個類,可以說'DefaultService'實現兩個接口:'Service1'和'Service2'。 Spring的java配置如下:Spring Java Config - 使用接口公開bean

@Bean 
Service1 defaultService() { 
    return new DefaultService(); 
} 

現在,我有另一個bean Foo需要'Service2'。

public class Foo implements AnotherInterface { 
    @Autowired 
    private Service2 service2; 
} 

和這個bean是通過Java配置也配置:

@Bean 
AnotherInterface anotherInterface(){ 
    return new Foo(); 
} 

春犯規這樣的配置。我想這是有道理的,因爲'DefaultService'暴露爲'Service1',而不是'Service2'(Foo要求)。

No qualifying bean of type [...Service2] found for dependency: expected at least 1 bean which qualifies ... 

我當然可以將DefaultService作爲Service2公開。但是如果有另一個需要Service1的bean呢?這個場景的Spring推薦是什麼?另一個(怪異)的問題,我發現,是下面的配置工作:

@Bean 
Service2 defaultService(){ // exposing the bean as Service2, to fix dependency on Foo 
    return new DefaultService(); 
} 

@Bean 
AnotherDependant anotherDependant(Service1 service1){ 
    return new AnotherDependant(service1); 
} 

如何彈簧鋼絲服務1到「AnotherDependant」(的配置聲明,其中它不是高興@Autowired我對第一個場景)? 我使用Spring 3.2.2.RELEASE,但我懷疑的版本真的很重要..

最好的解決方法我有是:

@Bean 
DefaultService defaultService(){ 
return new DefaultService(); 
} 

@Bean 
Service1 service1(){ 
return defaultService(); 
} 

@Bean 
Service2 service2(){ 
return defaultService(); 
} 

但是,這是相當難看......

================================================= ====================== 回覆@Oskar。 基本上,@Oskar建議的內容與在xml中聲明兩個相同......即在spring容器中創建兩個相同類的實例。

public interface Driveable {} 
public interface Vehicle {} 
public class Car implements Vehicle, Driveable{} 


@Configuration 
public class Config { 
    @Bean 
    public Vehicle vehicle() { 
     return new Car(); 
    } 
    @Bean 
    public Driveable driveable() { 
     return new Car(); 
    } 
} 

public class Main { 
    public static void main(String[] args) { 
     final AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Config.class); 

     final Driveable driveable = context.getBean("driveable", Driveable.class); 
     final Vehicle vehicle = context.getBean("vehicle", Vehicle.class); 
     System.out.println(driveable == vehicle); 
    } 
} 
+0

當然這是因爲java config和xml config是平等的;)morover你在這裏明確聲明瞭兩個不同的對象,'final Driveable driveable = context.getBean(「driveable」,Driveable.class);'如果你聲明瞭兩次你也會得到兩個對象,你可以得到一個bean,然後將其轉換到另一個接口,但這真的很難看 –

回答

1
public interface Driveable {} 
public interface Vehicle {} 

@Component 
public class Car implements Vehicle, Driveable{} 


@Configuration 
public class Config { 

    @Autowired 
    private Car car; 

    @Bean 
    public Vehicle vehicle() { 
     return car; 
    } 

    @Bean 
    public Driveable driveable() { 
     return car; 
    } 
} 

public class Application { 

    public static void main(String[] args) throws Exception { 
     final AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Config.class, Car.class); 
     final Driveable driveable = context.getBean("driveable", Driveable.class); 
     final Vehicle vehicle = context.getBean("vehicle", Vehicle.class); 
     System.out.println(driveable == vehicle); 
    } 

} 

考慮的問題汽車例子,

  1. 定義汽車作爲@Component。
  2. 在自動佈線的Config中聲明一個字段Car car
  3. 使用@Bean註釋方法返回autowired字段。

如果我們使用的是@ComponentScan,汽車部件將被自動選取。否則,如果我們自己創建上下文,我們可以在構造函數AnnotationConfigApplicationContext中傳遞Car類(如代碼所示)。

+0

以及你的實現有一個錯字'return new car',你想如何獲得@Component' ComponentScan'? –

+0

@Oskar:更正了錯字。組件可以通過AnnotationConfigApplicationContext對其構造函數中提供的類進行掃描。 – Mohit

+0

我現在看到,因爲你只是編輯主要實現的職位,但explicilty宣佈這樣的每個類可以使你的構造函數真的很大和凌亂 –

相關問題