在公司不同团队开发再整合时经常会遇到一个问题(公司架构基于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 的。
评论区