Spring中默认bean名称的生成策略/方式修改

在公司不同团队开发再整合时经常会遇到一个问题(公司架构基于SpringMVC),就是在使用注解的时候,两个模块里的这个资源都叫 xxxService ,这样在 Spring 启动的时候就会报错。错误如下

conflicts with existing, non-compatible bean definition of same name and class [xxxService ]  

之类,意思就是说两个 Bean 同名了,这样启动就报错了。

解决方法只能咱们自己手动修改 Bean 名称的生成策略了,比如直接使用类的全限定名称(com.app.xxx.service.xxxService)来作为 Bean 的名称~

AnnotationBeanNameGenerator 是 Spring 的默认生成策略,我们看一眼源码,其中buildDefaultBeanName 方法是生成名称的实现,具体如下:

String shortClassName = ClassUtils.getShortName(definition.getBeanClassName());  
return Introspector.decapitalize(shortClassName);  

这个默认的生成策略其实就是取首字母小写后的类名称,作为 Bean 名称。

这里 definition.getBeanClassName() 是获取全限定名称的,ClassUtils.getShortName() 是获取类名的,下面的 Introspector.decapitalize() 实际上就是把首字母变小写的。

这里要设置为全限定名称,我们可以新写一个类,例如 SherlockyAnnotationBeanNameGenerator ,继承 AnnotationBeanNameGenerator 之后重写buildDefaultBeanName方法,返回 definition.getBeanClassName() ,这样我们这个生成策略就写好了。

接下来还需要在 Spring 里面配置一下。打开 applicationContext.xml 文件,找到我们配置context:component-scan 这块,增加一个参数 name-generator=com.sherlocky.xxx.SherlockyAnnotationBeanNameGenerator 即可。

这时候所有 Bean 的默认名称就是我们设置的了,不过如果我们在类上显式的写了 Bean 的 id 的话,还是会用我们自定义的 Bean 的 name 的。