gpt4 book ai didi

java - 当我们在@Bean中创建新类,并在另一个@Bean中使用@Bean时会发生什么

转载 作者:行者123 更新时间:2023-12-02 09:36:19 29 4
gpt4 key购买 nike

我有 bean :

@Bean
public 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")
));
}

@Bean
public RestTemplate codesConverterRestTemplate(@Value("${readTimeoutMillis}") int readTimeout,
@Value("${connectTimeoutMillis}") int connectTimeout,
UriFactory uriFactory) {
System.out.println("codesConverterRestTemplate");
return getRestTemplate(readTimeout, connectTimeout);
}
@Bean
public 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 注入(inject)到前两个 bean 中。在启动时,我看到(使用 System.out.println)我的 bean 仅创建了一个(因为它们是单例),但我无法理解它是怎么回事,因为我使用不同的参数来调用前两个 bean 中的第三个 bean。所以我的问题是:整个事情是如何运作的。 new RestTemplate(factory) 将被调用多少次,如果我在两个具有不同参数的地方使用它,它如何可能是对第三个 bean 的一次调用。以这种方式创建 RestTemplate 是否是一个好方法

最佳答案

每次用@Bean注释的方法调用另一个用@Bean注释的方法时,@Configuration类不会实例化一个新对象。考虑这个例子:

@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

这是相关的documentation :

To put it another way, when you define a bean definition and it is scoped as a singleton, the Spring IoC container creates exactly one instance of the object defined by that bean definition. This single instance is stored in a cache of such singleton beans, and all subsequent requests and references for that named bean return the cached object. The following image shows how the singleton scope works:

在这种情况下,用@Bean注释的方法 bean 定义。

另外:

All @Configuration classes are subclassed at startup-time with CGLIB. In the subclass, the child method checks the container first for any cached (scoped) beans before it calls the parent method and creates a new instance.

换句话说,调用用@Bean注释的方法每次都应该返回相同的bean,无论参数如何。就您而言,我认为它是未定义的行为,因为除非您使用 depends-onSmartLifecycle 等选项,否则无法保证实例化的顺序。

关于java - 当我们在@Bean中创建新类,并在另一个@Bean中使用@Bean时会发生什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57481247/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com