3

我們的項目使用彈簧DI/IoC,所以我使用自動裝配來注入豆類。該程序需要在實例化過程中將參數傳遞給對象。參數在運行時已知(不在編譯時)。如何在使用彈簧自動佈線時傳遞構造函數參數?

如何在使用自動裝配時實現此目的。示例代碼如下。

接口 - 即時聊天

package com.example.demo.services; 

public interface IMessage { 
     String message(String name); 
} 

實現 -
SayHelloService

package com.example.demo.services; 

import org.springframework.stereotype.Service; 

@Service 
public class SayHelloService implements IMessage { 

    String id; 

    public SayHelloService(String id) { 
     super(); 
     this.id = id; 
    } 

    @Override 
    public String message(String name) { 
     return "Hello Dear User - " + name + ". Greeter Id: " + id ; 
    } 
} 

MasterService

package com.example.demo.services; 

import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.beans.factory.annotation.Qualifier; 
import org.springframework.stereotype.Service; 

@Service 
public class MasterService implements IMessage { 

    String creationTime; 

    MasterService() { 
     System.out.println("ms... default constructor"); 
     creationTime = Long.toString(System.currentTimeMillis()); 
    } 

    //classic java way of creating service 
    IMessage sayHelloServiceClassicWay = new SayHelloService(creationTime); 

    //how to achieve above using spring auto wiring. Below code does not exactly do same. 
    @Autowired 
    @Qualifier("sayHelloService") 
    IMessage sayHelloServiceAutoWired; 

    @Override 
    public String message(String name) { 
     return name.toString(); 
    }  
} 

現在,在上述程序(在MasterService)如何更換

即時聊天sayHelloServiceClassicWay =新SayHelloService(創建時間);

帶有彈簧等效代碼。

+0

爲變量創建一個getter和setter,然後在autowired字段上使用setter方法。 – user641887

+0

在您的配置xml中,將SayHelloService的bean中的「creationTime」屬性指定爲constructor-arg。 Spring將自動裝入它。 – Coder

+0

@ user641887,你可以添加一些代碼PLZ。 – samshers

回答

1

它的工作方式不同,在構造函數參數的Spring上下文中創建SayHelloService,然後Spring將自動裝入它。無XML congif例如:

class B1 { 
    @Autowired 
    B2 b2; 
} 

class B2 { 
    B2(int i) { 
    } 
} 

@Configuration 
class Config { 

    @Bean 
    B1 b1() { 
     return new B1(); 
    } 

    @Bean 
    B2 b2() { 
     return new B2(1); 
    } 
} 

在這個例子中,Spring將自動裝配B2其中有一個ARG

+0

你可以請添加一些代碼演示。它會是運行時。進一步我的項目不想避免xml配置。但任何方式plz分享你想要的。 – samshers

+0

thx回覆。代碼片段'return new B2(1);'value'1'仍然是編譯時,我需要在運行時傳遞它。 – samshers

+0

這不是必須的編譯時間,你可以從屬性中獲取該值。但是如果你說你需要在運行時注入一個bean(B2) - 你可以通過編程來完成,Spring沒有任何幫助,Spring的初始化在上下文構造 –

2

Spring不會以這種方式工作的構造。

您的兩個bean在執行和實例化方面過於耦合:第一個bean在構建時創建,第二個在運行時在參數構造函數中傳遞給它一個生成值。

即使通過依賴注入順序(@DependsOn@Order或兩個@Configuration哪一個取決於其他的)它不會解決,因爲運行時生成的值不是依賴你的問題,玩。

作爲一種變通方法,提供了一個方法,以重視在IMessage接口一旦creationTime可能是可接受的。
SayHelloService可能看起來像:

package com.example.demo.services; 

import org.springframework.stereotype.Service; 

    @Service 
    public class SayHelloService implements IMessage { 

     String id; 

     public SayHelloService(String id) { 
      super(); 
      this.id = id; 
     } 

     @Override 
     public void setId(String id){ 
      // you can add this check to enforce the immutability of id 
      if (this.id != null){//exception handling} 
      this.id = id; 
     } 

     @Override 
     public String message(String name) { 
      return "Hello Dear User - " + name + ". Greeter Id: " + id ; 
     } 
    } 

而且你可以用這種方式改變MasterService

private IMessage sayHelloServiceAutoWired; 

@Autowired 
MasterService(@Qualifier("sayHelloService") 
IMessage sayHelloServiceAutoWired) { 
    System.out.println("ms... default constructor"); 
    creationTime = Long.toString(System.currentTimeMillis()); 
    this.sayHelloServiceAutoWired = sayHelloServiceAutoWired; 
    this.sayHelloServiceAutoWired.setId(creationTime); 
} 

PS:自動裝配構造不是強制性的,但它是清潔劑沒有API來設置的依賴性班上。你也可以使用setter。

+0

gr8中再次回答。我仍然看到構造函數的自動裝配是一條路。否則自動佈線器可能是其他選擇。 – samshers

+0

@samshers謝謝。我試圖改進一點。問題的原因還不夠清楚。安裝者也是可能的,但它爲客戶端提供了更多的「權利」。如果它不是問題,它是有效的。 – davidxxx

相關問題