亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

當我們在@Bean 中創建新類,并在另一個@Bean 中使用@Bean 時會發生什么

當我們在@Bean 中創建新類,并在另一個@Bean 中使用@Bean 時會發生什么

qq_遁去的一_1 2023-06-04 15:27:27
我有豆子:@Beanpublic Map<String, Integer> currenciesCodesMap(@Value("${readTimeoutMillis}") int readTimeout,                                               @Value("${connectTimeoutMillis}") int connectTimeout,                                               UriFactory uriFactory) {    System.out.println("currenciesCodesMap");    RestTemplate restTemplate = getRestTemplate(readTimeout + 1, connectTimeout + 1);    List<Map> maps = Arrays.asList(Objects.requireNonNull(restTemplate.getForObject(uriFactory.getProgressiveCurrencyRates(), Map[].class)));        Map<String, Integer> currenciesCodesMap = maps.stream().collect(Collectors.toMap(                map -> (String) map.get("code"),                map -> (Integer) map.get("id")        ));}@Beanpublic RestTemplate codesConverterRestTemplate(@Value("${readTimeoutMillis}") int readTimeout,                                                   @Value("${connectTimeoutMillis}") int connectTimeout,                                                   UriFactory uriFactory) {        System.out.println("codesConverterRestTemplate");        return getRestTemplate(readTimeout, connectTimeout);    }@Beanpublic RestTemplate getRestTemplate(int readTimeout, int connectTimeout) {        CloseableHttpClient httpClient = HttpClientBuilder.create().disableCookieManagement().build();        HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(httpClient);        factory.setReadTimeout(readTimeout);        factory.setConnectTimeout(connectTimeout);        System.out.println("getRestTemplate");        return new RestTemplate(factory);    }我不想在每個 bean 中創建新的 RestTemplate,所以我決定在另一個 bean 中創建它,并將第三個 bean 注入到前兩個 bean 中。在啟動時,我看到(使用 System.out.println)我的 bean 只創建了一個(因為它們是單例),但我不明白它是怎么回事,因為我使用不同的參數在前兩個 bean 中調用第三個 bean。所以我的問題是:這整個事情是如何運作的。new RestTemplate(factory) 將被調用多少次,如果我在兩個具有不同參數的地方使用它,它怎么可能是對第三個 bean 的一次調用。以這種方式創建 RestTemplate 是一種好方法嗎
查看完整描述

1 回答

?
慕村9548890

TA貢獻1884條經驗 獲得超4個贊

類@Configuration不會在每次一個注解為 的方法@Bean調用另一個注解為 的方法時實例化一個新對象@Bean??紤]這個例子:


@Configuration

public class TestConfig {


? ? @Bean

? ? public String bean2(){

? ? ? ? String bean = bean1("bean2");

? ? ? ? System.out.println("bean2: " + bean);

? ? ? ? return bean;

? ? }


? ? @Bean

? ? public String bean3(){

? ? ? ? String bean = bean1("bean3");

? ? ? ? System.out.println("bean3: " + bean);

? ? ? ? return bean;

? ? }


? ? @Bean

? ? public String bean1(@Autowired(required = false) String name){

? ? ? ? System.out.println("bean1 " + name);

? ? ? ? return name;

? ? }

}

輸出如下,因為bean2()是先執行的:


bean1 bean2

bean2: bean2

bean3: bean2

這是相關文件:

換句話說,當您定義一個 bean 定義并將其限定為單例時,Spring IoC 容器會創建該 bean 定義定義的對象的一個實例。這個單個實例存儲在此類單例 bean 的緩存中,并且對該命名 bean 的所有后續請求和引用都返回緩存的對象。下圖顯示了單例作用域的工作原理:

在這種情況下,注釋為的方法@Bean?一個 bean 定義。

還:

所有 @Configuration 類都在啟動時使用 CGLIB 進行子類化。在子類中,子方法在調用父方法并創建新實例之前首先檢查容器中是否有任何緩存的(范圍內的)bean。

換句話說,@Bean無論參數如何,每次調用帶注釋的方法都應該返回相同的 bean。depends-on在您的情況下,我認為它是未定義的行為,因為除非您使用or之類的選項,否則不能保證實例化的順序SmartLifecycle


查看完整回答
反對 回復 2023-06-04
  • 1 回答
  • 0 關注
  • 224 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號