簡體   English   中英

Spring bean與運行時構造函數參數

[英]Spring bean with runtime constructor arguments

我想在Spring Java配置中創建一個Spring bean,並在運行時傳遞一些構造函數參數。 我創建了以下Java配置,其中有一個bean fixedLengthReport ,它需要構造函數中的一些參數。

@Configuration
public class AppConfig {

    @Autowrire
    Dao dao;

    @Bean
    @Scope(value = "prototype")
    **//SourceSystem can change at runtime**
    public FixedLengthReport fixedLengthReport(String sourceSystem) {
         return new TdctFixedLengthReport(sourceSystem, dao);
    }
}

但我收到的錯誤是sourceSystem無法連接,因為沒有找到bean。 如何使用運行時構造函數參數創建bean?

我使用的是Spring 4.2

您可以將原型bean與BeanFactory一起使用。

@Configuration
public class AppConfig {

   @Autowired
   Dao dao;

   @Bean
   @Scope(value = "prototype")
   public FixedLengthReport fixedLengthReport(String sourceSystem) {
       return new TdctFixedLengthReport(sourceSystem, dao);
   }
}

@Scope(value = "prototype")意味着Spring不會在啟動時實例化bean,但會在以后按需執行。 現在,要自定義原型bean的實例,您必須執行以下操作。

@Controller
public class ExampleController{

   @Autowired
   private BeanFactory beanFactory;

   @RequestMapping("/")
   public String exampleMethod(){
      TdctFixedLengthReport report = 
         beanFactory.getBean(TdctFixedLengthReport.class, "sourceSystem");
   }
}

注意,因為你的bean在啟動時無法實例化,你不能直接自動裝配你的bean; 否則Spring會嘗試實例化bean本身。 此用法將導致錯誤。

@Controller
public class ExampleController{

   //next declaration will cause ERROR
   @Autowired
   private TdctFixedLengthReport report;

}

你的代碼看起來很好,用參數獲取原型使用BeanFactory#getBean(String name,Object ... args)方法。

看看Spring Java Config:如何使用運行時參數創建原型范圍的@Bean? BeanFactory#getBean(String name,Object ... args)將是您正在尋找的。

我想你的IDEA(在我的情況下,IntelliJ IDEA版本15)給你錯誤,它不是運行時/編譯時錯誤。

在IntelliJ中,您可以更改彈簧檢查的設置。

  • 轉到文件 - >設置。
  • 在搜索框中鍵入檢查。
  • 轉到Spring Core-> Code-> Autowire for Bean Classes。
  • 從“錯誤”更改為“弱警告”

這可以通過Spring的ObjectProvider<>類實現,該類是在Spring 4.3中引入的。 有關其他詳細信息,請參閱Spring的文檔

要點是為要提供的對象定義bean工廠方法,在您的使用者中注入ObjectProvider<>並創建要提供的對象的新實例。

public class Pair
{
    private String left;
    private String right;

    public Pair(String left, String right)
    {
        this.left = left;
        this.right = right;
    }

    public String getLeft()
    {
        return left;
    }

    public String getRight()
    {
        return right;
    }
}

@Configuration
public class MyConfig
{
    @Bean
    @Scope(BeanDefinition.SCOPE_PROTOTYPE)
    public Pair pair(String left, String right)
    {
        return new Pair(left, right);
    }
}

@Component
public class MyConsumer
{
    private ObjectProvider<Pair> pairProvider;

    @Autowired
    public MyConsumer(ObjectProvider<Pair> pairProvider)
    {
        this.pairProvider = pairProvider;
    }

    public void doSomethingWithPairs()
    {
        Pair pairOne = pairProvider.getObject("a", "b");
        Pair pairTwo = pairProvider.getObject("z", "x");
    }
}

注意:您實際上沒有實現ObjectProvider<>接口; Spring會自動為您做到這一點。 您只需要定義bean工廠方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM