有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

实现多个接口的JavaSpringbean

我有一个bean,它实现了两个接口。基本代码如下:

interface InterfaceA {
  ...
}

interface InterfaceB {
  ...
}

public class ClassC implements InterfaceA, InterfaceB {
  ...
}

在我的AppConfig中,我指定了以下内容:

@Bean(name = "InterfaceA")
public InterfaceA interfaceA() {
    return new ClassC();
}

@Bean(name = "InterfaceB")
public InterfaceB interfaceB() {
    return new ClassC();
}

我是这么用的:

public class MyClass {

    @Inject
    private final InterfaceA a;

    public MyClass(@Named("InterfaceA") InterfaceA a) {
        this.a = a;
    }
     ...
}

然而,Spring抱怨说:

No qualifying bean of type [com.example.InterfaceA] is defined: expected single matching bean but found 2: InterfaceA, InterfaceB

对于EJB here也提出了类似的问题,但我找不到任何关于springbean的问题。有人知道原因吗

解决方法是引入一个新的接口,扩展InterfaceAInterfaceB,然后让ClassC实现它。然而,由于框架的限制,我不愿意改变我的设计


共 (2) 个答案

  1. # 1 楼答案

    谢谢你提出的好问题

    在我的例子中,我创建了一个扩展A和B的接口:

    public interface InterfaceC extends InterfaceA, InterfaceB {}
    

    。。。通用实现实现了统一接口:

    public class ClassC implements InterfaceC {
      //...
    }
    

    这个统一的接口允许创建一个bean:

    @Bean
    public InterfaceC implementationForAandB() {
        return new ClassC();
    }
    

    然后,Spring框架能够将通用实现注入或自动连接到以主接口表示的依赖项:

    public class MyClass {
    
        @Inject
        private final InterfaceA a;
    
        @Inject
        private final InterfaceB b;
    
        public MyClass(InterfaceA a, InterfaceB b) {
            //...
        }
    

    }

  2. # 2 楼答案

    春天是对的。。。当你写作的时候

    @Bean(name = "InterfaceA")
    public InterfaceA interfaceA() {
        return new ClassC();
    }
    
    @Bean(name = "InterfaceB")
    public InterfaceB interfaceB() {
        return new ClassC();
    }
    

    Spring创建了ClassC对象,一个名为InterfaceA,另一个名为InterfaceB,都实现了InterfaceA和InterfaceB

    然后当你写作时:

    @Inject
    private final InterfaceA a;
    

    您要求Spring找到一个实现InterfaceA的bean,但是如上所述,有两个错误

    您可以只创建一个类型为ClassC的对象,或者使用@Qualifier@Named注释:

    @Inject
    @Named("InterfaceA")
    private final InterfaceA a;
    

    这样,您明确地要求Spring找到名为InterfaceA的bean,希望它现在是唯一的