Reputation: 2794
We have a Spring 4.0.5.RELEASE based application, and by mistake, we introduced two beans with the same name. Both beans are instances of RestTemplate version 4.2.2, the Spring framework to make HTTP calls:
First "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;
}
Second "restTemplate" bean, totally raw
@Bean(name = "restTemplate")
protected RestTemplate restTemplate() {
RestTemplate restTemplate = new RestTemplate();
return restTemplate;
}
The main difference between the two, is the error handling. And this is the issue:
We have four server running, and we deployed the same war file in each one of them. As per logs, we are 100% sure that in the first two servers, the restTemplate instance with error handling is being used. And in the other two, the instance without error handling is not being used.
Why Spring behaves like that? It is injecting the "restTemplate" bean in a totally non-deterministic way. What might be the causes of this behaving? I would expect to have the same instance of "restTemplate" in the all of 4 servers.
Here I put the logs, showing what I'm trying to explain. Take a look to the bold statements!!
Sever One:
[timestamp=19:09:23.846] [thread="localhost-startStop-1"] [session="undefined"] [request="undefined"] [level=INFO ] [logger=o.s.b.f.s.DefaultListableBeanFactory] [class=org.springframework.beans.factory.support.DefaultListableBeanFactory] [line=839] - Overriding bean definition for bean 'restTemplate' with a different definition: replacing [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=configCommon; factoryMethodName=restTemplate; initMethodName=null; destroyMethodName=(inferred); defined in com.service.common.config.ConfigCommon] with [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=configCentralReservations; factoryMethodName=restTemplate; initMethodName=null; destroyMethodName=(inferred); defined in com.service.centralreservations.config.ConfigCentralReservations]
Server Two:
[timestamp=19:04:41.717] [thread="localhost-startStop-1"] [session="undefined"] [request="undefined"] [level=INFO ] [logger=o.s.b.f.s.DefaultListableBeanFactory] [class=org.springframework.beans.factory.support.DefaultListableBeanFactory] [line=839] - Overriding bean definition for bean 'restTemplate' with a different definition: replacing [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=configCentralReservations; factoryMethodName=restTemplate; initMethodName=null; destroyMethodName=(inferred); defined in com.service.centralreservations.config.ConfigCentralReservations] with [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=configCommon; factoryMethodName=restTemplate; initMethodName=null; destroyMethodName=(inferred); defined in com.service.common.config.ConfigCommon]
Upvotes: 0
Views: 1439
Reputation: 691635
I can imagine many reasons:
Class.getMethods()
are returned in an unspecified order, You should rather ask yourself: why should it use one over the other? Have you specified an order anywhere? Does Spring offer any guarantee in that regard? If it doesn't, you shouldn't assume anything.
Upvotes: 1