When I try to register two beans (one of aliases of the first bean corresponds to method name (= future id) of the second bean, the creation of second bean is ignored. The context starts without any exception.
@Configuration
public class MyConfiguration {
@Bean({"name1", "name2"})
public MyInterface myBean() {
return new MyFirstBean();
}
@Bean
public MyInterface name2() {
return new MySecondBean();
}
}
MyMap
in the following example contains only one bean, actually: name1 -> MyFirstBean
@Autowired
Map<String, MyInterface> myMap;
I'm not sure if it is a bug or a feature. In my opinion NoUniqueBeanDefinitionException should be thrown in this case.
What do you think?
Comment From: snicoll
It depends. Given that myBean
claims name1
and name2
, it sounds logical that MySecondBean
isn't created. We need to put a priority somewhere. If we did the reverse, you could equally claim that MyFirstBean
isn't used despite it declaring an alias for name2
.
Having said that, I was expecting this to fail with Spring Boot as we prevent bean overriding by default. It did not and that felt a little bit more surprising. Flagging to get more feedback from the team.
Comment From: levitin
If we did the reverse, you could equally claim that MyFirstBean isn't used despite it declaring an alias for name2
Yes, another direction would also cause an unpleasant surprise. But it is even worse, if giving any bean a "harmless" alias would suddenly exclude another existing bean in case of name matching. I think, such side effect could be really dangerous, perhaps it can be even a security issue.
In my opinion, in such case as described above, it would be much more safer, if the context would not even start at all.
Is there any reason not to treat every bean name and every alias as unique?
Comment From: jhoeller
There are indeed two inconsistencies in our overriding checks between bean definition names and aliases: Not only is a new bean definition overriding an existing alias not prevented when allowBeanDefinitionOverriding=false (like in Boot by default), the factory also silently registers a new bean definition but does not remove a same-named alias when allowBeanDefinitionOverriding=true.
In other words, bean definition overriding between bean definition names and aliases is a feature, but a later definition should consistently override an existing definition - so in our scenario here, the name2
method should override the existing name2
alias. And with overriding deactivated, it should consistently throw an exception when encountering such an attempted override for an existing alias.
I'll revise this for 6.0 M3.