当Spring找到两个同名的bean时会做什么?

时间:2015-12-28 17:39:16

标签: java spring rest jvm

我们有一个基于Spring 4.0.5.RELEASE的应用程序,并且错误地引入了两个具有相同名称的bean。这两个bean都是RestTemplate版本4.2.2的实例,它是用于进行HTTP调用的Spring框架:

首先是“restTemplate”bean

@Bean(name = "restTemplate")
protected RestTemplate restTemplate() {
    RestTemplate restTemplate = new RestTemplate();
    restTemplate.setErrorHandler(new RestTemplateErrorHandler());

    List<HttpMessageConverter<?>> messageConverters = new ArrayList<HttpMessageConverter<?>>();
    MappingJackson2HttpMessageConverter jacksonConverter = new MappingJackson2HttpMessageConverter();
    ObjectMapper mapper = new ObjectMapper();
    mapper.configure(SerializationFeature.WRAP_ROOT_VALUE, true);
    // Disable exceptions on unknown incoming properties
    mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    jacksonConverter.setObjectMapper(mapper);
    messageConverters.add(jacksonConverter);
    messageConverters.add(new Jaxb2RootElementHttpMessageConverter());
    messageConverters.add(new StringHttpMessageConverter());

    restTemplate.setMessageConverters(messageConverters);

    return restTemplate;
}

第二个“restTemplate”bean,完全是原始的

@Bean(name = "restTemplate")
protected RestTemplate restTemplate() {
    RestTemplate restTemplate = new RestTemplate();

    return restTemplate;
}

两者的主要区别在于错误处理。这就是问题所在:

我们有四个服务器在运行,我们在每个服务器上部署了相同的war文件。根据日志,我们100%确定在前两个服务器中,正在使用带有错误处理的restTemplate实例。而在另外两个中,没有使用没有错误处理的实例。

为什么Spring表现得那样?它以完全不确定的方式注入“restTemplate”bean。这种表现的原因可能是什么?我希望在所有4台服务器中都有相同的“restTemplate”实例。

这里我放了日志,显示了我想要解释的内容。看看大胆的陈述!!

Sever One:

[timestamp = 19:09:23.846] [thread =“localhost-startStop-1”] [session =“undefined”] [request =“undefined”] [level = INFO] [logger = osbfsDefaultListableBeanFactory] ​​[class = org.springframework.beans.factory.support.DefaultListableBeanFactory] ​​[line = 839] - 使用不同的定义覆盖bean'restTemplate'的bean定义:替换[root bean:class [null];范围=;抽象= FALSE; lazyInit = FALSE; autowireMode = 3; dependencyCheck = 0; autowireCandidate = TRUE;初级= FALSE; factoryBeanName = configCommon; factoryMethodName = restTemplate; initMethodName = NULL; destroyMethodName =(推断);使用[Root bean:class [null];在com.service.common.config.ConfigCommon ]中定义的;范围=;抽象= FALSE; lazyInit = FALSE; autowireMode = 3; dependencyCheck = 0; autowireCandidate = TRUE;初级= FALSE; factoryBeanName = configCentralReservations; factoryMethodName = restTemplate; initMethodName = NULL; destroyMethodName =(推断); 在com.service.centralreservations.config.ConfigCentralReservations中定义]

服务器二:

[timestamp = 19:04:41.717] [thread =“localhost-startStop-1”] [session =“undefined”] [request =“undefined”] [level = INFO] [logger = osbfsDefaultListableBeanFactory] ​​[class = org.springframework.beans.factory.support.DefaultListableBeanFactory] ​​[line = 839] - 使用不同的定义覆盖bean'restTemplate'的bean定义:替换[root bean:class [null];范围=;抽象= FALSE; lazyInit = FALSE; autowireMode = 3; dependencyCheck = 0; autowireCandidate = TRUE;初级= FALSE; factoryBeanName = configCentralReservations; factoryMethodName = restTemplate; initMethodName = NULL; destroyMethodName =(推断);使用[Root bean:class [null];在com.service.centralreservations.config.ConfigCentralReservations ]中定义的;范围=;抽象= FALSE; lazyInit = FALSE; autowireMode = 3; dependencyCheck = 0; autowireCandidate = TRUE;初级= FALSE; factoryBeanName = configCommon; factoryMethodName = restTemplate; initMethodName = NULL; destroyMethodName =(推断); 在com.service.common.config.ConfigCommon中定义]

1 个答案:

答案 0 :(得分:1)

我可以想象很多原因:

  • 类路径扫描以未指定的顺序返回配置注释的类
  • 配置类存储在没有指定顺序的HashMap中
  • Class.getMethods()返回的方法以未指定的顺序返回,
  • 等。等。

你应该问自己:为什么要使用一个而不是另一个?你有没有在任何地方指定订单? Spring是否在这方面提供任何保证?如果它没有,你就不应该做任何事情。