在公司不同团队开发再整合时经常会遇到一个问题(公司架构基于SpringMVC),就是在使用注解的时候,两个模块里的这个资源都叫 `xxxService` ,这样在 Spring 启动的时候就会报错。错误如下
```java
conflicts with existing, non-compatible bean definition of same name and class [xxxService ]
```
之类,意思就是说两个 Bean 同名了,这样启动就报错了。
解决方法只能咱们自己手动修改 Bean 名称的生成策略了,比如直接使用类的全限定名称(com.app.xxx.service.xxxService)来作为 Bean 的名称~
`AnnotationBeanNameGenerator` 是 Spring 的默认生成策略,我们看一眼源码,其中`buildDefaultBeanName` 方法是生成名称的实现,具体如下:
```java
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 的。
Spring中默认bean名称的生成策略/方式修改