从spring的启动过程聊透BeanName的覆盖
这篇博客将把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等等注解是不会起作用的。