spring - SpringBoot:如何注入两个具有相同名称的类
问题描述
在我的应用程序中,我有两个具有相同名称的类,但当然在不同的包中。
这两个类都需要在应用程序中注入;不幸的是,我收到以下错误消息:
Caused by: org.springframework.context.annotation.ConflictingBeanDefinitionException: Annotation-specified bean name 'myFeature' for bean class [org.pmesmeur.springboot.training.service.feature2.MyFeature] conflicts with existing, non-compatible bean definition of same name and class [org.pmesmeur.springboot.training.service.feature1.MyFeature]
我的问题可以通过以下示例重现:
@Component
@EnableConfigurationProperties(ServiceProperties.class)
public class MyService implements IService {
private final ServiceProperties serviceProperties;
private final IProvider provider;
private final org.pmesmeur.springboot.training.service.feature1.IMyFeature f1;
private final org.pmesmeur.springboot.training.service.feature2.IMyFeature f2;
@Autowired
public MyService(ServiceProperties serviceProperties,
IProvider provider,
org.pmesmeur.springboot.training.service.feature1.IMyFeature f1,
org.pmesmeur.springboot.training.service.feature2.IMyFeature f2) {
this.serviceProperties = serviceProperties;
this.provider = provider;
this.f1 = f1;
this.f2 = f2;
}
...
package org.pmesmeur.springboot.training.service.feature1;
public interface IMyFeature {
void print();
}
package org.pmesmeur.springboot.training.service.feature1;
import org.springframework.stereotype.Component;
@Component
public class MyFeature implements IMyFeature {
@Override
public void print() {
System.out.print("HelloWorld");
}
}
package org.pmesmeur.springboot.training.service.feature2;
public interface IMyFeature {
void print();
}
package org.pmesmeur.springboot.training.service.feature2;
import org.springframework.stereotype.Component;
@Component
public class MyFeature implements IMyFeature {
@Override
public void print() {
System.out.print("FooBar");
}
}
如果我为我的班级使用不同的名字MyFeature
,我的问题就消失了!!!
我习惯使用 Guice,这个框架没有这种问题/限制
似乎spring依赖注入框架只使用类名而不是包名+类名来选择它的类。
在“现实生活”中,我在一个更大的项目中遇到了这个问题,我强烈希望不必重命名我的课程:有人可以帮助我吗?
最后一点,我宁愿避免“技巧”,例如
@Qualifier(value = "ABC")
在注入我的类时使用:在我的示例中,找到正确的实例应该没有歧义,MyFeature
因为它们没有实现相同的接口
解决方案
简单地重新实现BeanNameGenerator
为通过名称声明/实例化的 bean 添加了一个新问题
@Component("HelloWorld")
class MyComponent implements IComponent {
...
}
@Qualifier(value = "HelloWorld") IComponent component
我通过扩展AnnotationBeanNameGenerator
和重新定义方法解决了这个问题buildDefaultBeanName()
static class BeanNameGeneratorIncludingPackageName extends AnnotationBeanNameGenerator {
public BeanNameGeneratorIncludingPackageName() {
}
@Override
public String buildDefaultBeanName(BeanDefinition beanDefinition, BeanDefinitionRegistry beanDefinitionRegistry) {
return beanDefinition.getBeanClassName();
}
}
推荐阅读
- python - pyparsing 语法以提取 Python 片段的部分
- amazon-ec2 - 无法使用负载平衡器 (https) 连接到 XDBC 服务器
- javascript - 如何链接 Firebase auth Android 应用和网络应用?
- asp.net-web-api - 发布请求在 xamarin 表单中不起作用
- ruby-on-rails - taglib-ruby 如何替换专辑封面
- svn - 将现有的 Git 存储库推送到 SVN:git svn dcommit 错误
- visual-studio - 打开文件时禁用自动差异
- c++ - 构建具有一个共同成员的数对链
- r - 我想使用正则表达式摆脱字符向量中具有精确模式的单词,但不知道如何
- spring - 如何使用 Spring Webflux 从 GridFS 流式传输视频?