在我的应用程序中,我有两个类具有相同的名称,但当然在不同的包中。
需要在应用程序中注入这两个类;不幸的是,我得到了以下错误消息:
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的正确实例不应含糊不清,因为它们没有实现相同的接口。
发布于 2019-08-07 14:28:53
只需重新实现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();
}
}发布于 2019-07-22 07:00:08
您可以为每个组件指定一个值,例如@Component(value="someBean"),然后将其注入@Qualifier。
@Autowired
public SomeService(@Qualifier("someBean") Some s){
//....
}发布于 2019-07-22 07:07:35
你可以这样做;
包内a
public class MyFeature implements IMyFeature {
@Override
public void print() {
System.out.print("FooBar");
}
}包内b
public class MyFeature implements IMyFeature {
@Override
public void print() {
System.out.print("HelloWorld");
}
}在某些配置类中;
@Configuration
public class Configuration {
@Bean
public a.MyFeature f1() {
return new a.MyFeature();
}
@Bean
public b.MyFeature f2() {
return new b.MyFeature();
}
}然后,您可以自动使用名称f1和f2,这是它们各自的bean构造函数方法的名称。
您可以使用
@Component("f1")&@Component("f2")做类似的事情
即使在不同的包中实现了不同的接口,相同的bean名称也会导致这个问题,您必须使用某种自定义命名来区分。与使用上面的解决方案相比,使用一些自定义弹簧逻辑就太难看了。
https://stackoverflow.com/questions/57140430
复制相似问题