[英]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的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.