![](/img/trans.png)
[英]Creating a different instance of an Object with scope prototype in OSGi using Spring
[英]Difference between creating new instance and using scope prototype annotation in Spring
我的應用程序正在監聽交換(使用rabbitMQ
),希望接收一些API數據,然后將其重定向到相關位置。
我正在使用rxJava
來訂閱這些更改,當目的是打開一個新線程並通過每次創建RestClient
發送請求時 - >它將接收數據,解析它,發送它然后將響應發送回隊列。
我的問題是我希望每次都能創建一個RestClient的新實例。 考慮使用Springs Scope注釋: @Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
但似乎無法理解如何使用它,如果我每次都使用new RestClient
會有什么不同。
你能解釋一下使用getBean
不是使用new
的好處嗎?
這是代碼:
class MyManager {
@Autowired
private WebApplicationContext context;
....
...
...
@PostConstruct
myListener.subscribeOn(Schedulers.computation()).subscribe(this::handleApiRequest);
private void handleApiRequest(ApiData apiData){
// Option 1:
RestClient client = new RestClient();
client.handleApiRequest(apiData);
//Option 2:
// use somehow the prototype?
RestClient x = (RestClient)context.getBean("restTest")..
}
}
@Service
//@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE) //NEEDED??
class RestClient {
private String server;
private RestTemplate rest;
private HttpHeaders headers;
ResponseEntity<String> responseEntity;
@PostConstruct
private void updateHeaders() {
headers.add(Utils.CONTENT_TYPE, Utils.APPLICATION_JSON);
headers.add(Utils.ACCEPT, Utils.PREFIX_ALL);
}
public void handleApiRequest(ApiData apiRequest) {
sendRequest(apiRequest); //implemented
sendResponse(); //implemented
}
}
@Bean(name = "restTest")
@Scope("prototype")
public RestClient getRestTemplate() {
return new RestClient();
}
首先,resttemplate是線程安全的 。 不要根據請求或使用新關鍵字(構造函數)對其進行實例化,這是一個糟糕的設計。 因為你在這里注釋掉了@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
; 默認情況下,spring將創建一個RestClient
的單例bean,無論你在哪里自動裝配,你都會得到相同的RestClient
實例; 所以你做得對
@Service
//@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE) //NEEDED??
class RestClient {
我在這里有一個問題,在RestClient中,你在哪里實例化private RestTemplate rest;
我在你發布的代碼中沒有看到這一點
如果您按照建議從原型范圍轉移到單例范圍,則可以使用@Autowired RestClient restClient;
代替
@Autowired private WebApplicationContext context;
RestClient x = (RestClient)context.getBean("restTest")
更少的樣板。
當你使用context.getBean
,返回的實例是一個Spring bean,spring處理依賴注入,配置,生命周期回調....... 當你剛剛使用new
創建它時,沒有發生這種情況。 在您給出的示例中,只有在使用context.getBean
才會調用@PostConstruct
方法。
當您使用context.getBean()返回的任何bean時,該bean的生命周期將由Spring處理。
但是如果用新實例初始化bean,則負責創建對象及其生命周期。 (因此@PostConstruct和該類中的其他spring注釋將毫無意義。)並且不會注入該bean中的任何依賴項。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.