What is the precedence of Spring beans definitions?
java, spring
Solution
Beans are registered in the order that are found in xml definition file.
Scanned beans are registered at point that the xml tag is found but scanned beans cannot override previously registered bean definitions.
Xml beans definitions can override any previously bean definition if `DefaultListableBeanFactory.allowBeanDefinitionOverriding` is true (by default).
So XML Wins.
If you put the component-scan tag first, xml beans will override scanned ones. If you put it last, scanned beans will be ignored.
Edit
Aliases have diferent behavior if declared in name attribute in a bean definition or declared using the alias tag.
- aliases declared with the alias tag hides any later bean definition with the same name.
- aliases declared in name attribute prevent any other bean definition to use the same name by throwing a `BeanDefinitionParsingException`.
For example:
<bean id="foo" name="bar" class="Foo" />
<bean id="bar" class="Bar" /> -- throw Exception (name bar is in use)
but
<bean id="foo" class="Foo" />
<alias name="foo" alias="bar" />
<bean id="bar" class="Bar" /> -- Hidden by alias no exception thrown
The diference is that `BeanDefinitionParserDelegate` hold a list of names and aliases in use at the same bean level of beans element nesting and check for name uniqueness when parsing bean definitions.
The alias tag is processed directly by `DefaultBeanDefinitionDocumentReader.processAliasRegistration()` and the parser delegate is unaware of this names.
I don't know if it's a bug or intentional but reference does not say anything about and seem to be expected that the internal and external declarations of aliases have the same behavior.
Problem
When several Spring beans are defined with the same name, which one will hide the others? Let's say I have several classes annotated with `@Component("bean")` in the package org.example, plus an applicationContext.xml that contains: ``` <context:component-scan base-package="org.example"/> <alias name="aliasedBean" alias="bean"/> <bean id="aliasedBean" class="org.example.AliasedBean"/> <bean id="bean" class="org.example.XmlBean"/> <import resource="otherApplicationContext.xml"/> ``` Which bean will be retrieved when I do an `applicationContext.getBean("bean")`? According to the Spring documentation: Every bean has one or more identifiers. These identifiers must be unique within the container that hosts the bean. However, I know (because I tested) that Spring won't complain when this is done. One definition will hide the others. But I couldn't find out what was the rule. I want to do this for testing purpose. I use annotation based configuration in order to define real (production) beans. Then I want to use a test-specific XML configuration file to override these definitions and inject mock beans. Edit: Since you were several to ask for logs, I spent some time creating some. Here are they: ``` 0 INFO org.springframework.context.support.ClassPathXmlApplicationContext - Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@3934f69a: startup date [Wed Mar 06 23:04:35 CET 2013]; root of context hierarchy 45 INFO org.springframework.beans.factory.xml.XmlBeanDefinitionReader - Loading XML bean definitions from class path resource [applicationContext.xml] 223 INFO org.springframework.beans.factory.support.DefaultListableBeanFactory - Overriding bean definition for bean 'bean': replacing [Generic bean: class [org.example.AnnotatedBean]; scope=singleton; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; defined in file [/Users/etienne/Documents/Développement/Registre/workspace/SpringPrecedence/target/classes/org/example/AnnotatedBean.class]] with [Generic bean: class [org.example.XmlBean]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; defined in class path resource [applicationContext.xml]] 223 INFO org.springframework.beans.factory.xml.XmlBeanDefinitionReader - Loading XML bean definitions from class path resource [otherApplicationContext.xml] 246 INFO org.springframework.beans.factory.support.DefaultListableBeanFactory - Overriding bean definition for bean 'bean': replacing [Generic bean: class [org.example.XmlBean]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; defined in class path resource [applicationContext.xml]] with [Generic bean: class [org.example.ImportedXmlBean]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; defined in class path resource [otherApplicationContext.xml]] 290 INFO org.springframework.beans.factory.support.DefaultListableBeanFactory - Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@6aba4211: defining beans [bean,org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,aliasedBean,org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor]; root of factory hierarchy 290 INFO org.example.AliasedBean - Construction of AliasedBean. 302 INFO org.example.Main - Application context loaded. 302 INFO org.springframework.context.support.ClassPathXmlApplicationContext - Closing org.springframework.context.support.ClassPathXmlApplicationContext@3934f69a: startup date [Wed Mar 06 23:04:35 CET 2013]; root of context hierarchy 302 INFO org.springframework.beans.factory.support.DefaultListableBeanFactory - Destroying singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@6aba4211: defining beans [bean,org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,aliasedBean,org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor]; root of factory hierarchy ``` After some tests, I found out that I get an exception during context creation if: - I have two `@Component("bean")` or - I have two `<bean id="bean"/>` elements in the same XML file.