这篇博客将把Spring的BeanName的覆盖问题聊透

Spring有一套BeanName的覆盖规则,这套规则是隐含在Spring源码中的,并没有做单独的抽象,也不支持定制化配置,所以想要弄懂有一点难度。

当项目越来越大,引入的包越来越多,如果这些包里面也有基于Spring开发的包的话,那么项目将越来越容易发生BeanName碰撞的问题,而Spring对于BeanName碰撞的情况并不一定会抛出异常,而有可能采用内置的一套规则进行BeanDefinition的相互覆盖,导致项目发生一些难以察觉的bug。

这种BeanName覆盖的情况多数发生在Xml配置和注释混用的情况下。

先看看AnnotationConfigApplicationContext

上篇博客我们讲了一下ClassPathXmlApplicationContext解析Xml的总体流程,没有深入到细节。ClassPathXmlApplicationContext负责解析Xml,对应Xml的spring启动方式,我们可以这样启动spring:

ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");

相对应的AnnotationConfigApplicationContext代表的是以纯注解的方式启动spring:

ApplicationContext context = new AnnotationConfigApplicationContext("com.nowcoder.spring");

这里传入的参数是扫描的Root包,spring会扫描这个包下的所有Class。

AnnotationConfigApplicationContext的创建

Xml和注解配置Spring混用是怎么实现的?

如果我们纯粹的使用Xml作为Spring的启动方式的话,那么全部bean的组装是有Xml文件控制的,类中定义的@Autowired、@Component等等注解是不会起作用的。