0

我試圖在Java Spring引導應用程序中創建工廠方法。但不是手動實例化一個對象,我想從DI容器中獲取它。那可能嗎?從DI容器獲取新實例的工廠方法

public interface PaymentService { 
    public Payment createPayment(String taskId); 
} 

public class PaymentServiceImplA implements PaymentService { 
    private JobService jobService; 
    private ApplicationService applicationService; 
    private UserService userService; 
    private WorkService workService; 

    @Inject 
    public PaymentServiceImplA(JobService jobService, UserService userService, WorkService workService, 
     ApplicationService applicationService) { 
     this.jobService = jobService; 
     this.applicationService = applicationService; 
     this.userService = userService; 
     this.workService = workService; 
     //removed other constructor injected dependencies 
    } 
} 

收到錯誤「無類型的符合條件的bean的com.test.mp.service.PaymentServiceImplA「可用」時的getBean方法被調用。

@Configuration 
public class PaymentFactory { 

    private ApplicationContext applicationContext; 

    @Inject 
    public PaymentFactory(ApplicationContext applicationContext) {  
     this.applicationContext = applicationContext; 
    } 

    @Bean 
    public PaymentService paymentService(){ 
     //Using getBean method doesn't work, throws error mentioned above    
     if(condition == true) 
      return applicationContext.getBean(PaymentServiceImplA.class); 
     else 
      return applicationContext.getBean(PaymentServiceImplB.class); 

    } 
} 
+1

它應該是可用的,因爲?我沒有看到「@ Service」,所以它不會被檢測到。另外,我建議編寫自己的'@ Conditional'規則(取決於條件,你甚至可以使用其中一個現有的規則) –

+0

我想使用DI容器,因爲實現類需要大量的這些對象反過來有很多依賴關係,所以我不想手動實例化它們,我將檢查@Conditional規則,謝謝! – Baga

+0

這與那些沒有'@ Service'有關嗎?我強烈建議看看有條件的規則(這些規則也可以應用於帶註釋的類) –

回答

0

這就是我現在最終解決這個問題的方法。通過注入bean方法來實例化實現對象所需的依賴關係。

@Configuration 
public class PaymentFactory { 

    //private ApplicationContext applicationContext; 

    public PaymentFactory() {  
     //this.applicationContext = applicationContext; 
    } 

    @Bean 
    public PaymentService paymentService(JobService jobService, UserService userService 
    , WorkService workService, ApplicationService applicationService){ 

     if(condition == true){ 
      return new PaymentServiceImplA(jobService, userService, workService, 
    applicationService); 
     } 
     else { 
      return new PaymentServiceImplB(jobService, userService, workService, 
    applicationService); 
     } 
    } 
} 
1

這可以在配置文件中創建兩個bean後解決。即

@Bean 
public PaymentService paymentServiceA(){ 
return new PaymentServiceImplA(); 
} 

@Bean 
public PaymentService paymentServiceB(){ 
return new PaymentServiceImplA(); 
} 

和返回豆應該是:

@Bean 
    public PaymentService paymentService(){    
     if(condition == true) 
      return paymentServiceA(); 
     else 
      return paymentServiceB(); 

    } 
+0

另外,您可以在PaymentServiceImplA和PaymentServiceImplB類上添加任何註釋(組件/服務),以避免手動編寫配置 –

+0

謝謝!試試這個並且還原 – Baga

+0

而不是使用'return new PaymentServiceImplA();'有沒有辦法從DI連續獲取對象ainer。由於實例化對象所需的嵌套依賴關係很多。 – Baga

0

是它可能與ServiceLocatorFactoryBean的幫助。事實上,如果我們編寫Factory代碼來創建實現對象,那麼在該實現類類中,如果我們注入任何存儲庫或其他對象,那麼它將拋出異常。原因是如果用戶是創建對象,那麼對於這些​​對象,Spring不允許注入依賴項。所以最好用Spring使用工廠模式來創建實現對象。嘗試使用ServiceLocatorFactoryBean

+0

謝謝!我會試試這個。如果您可以添加任何有用的示例代碼。 – Baga