Spring Bean 实现多个接口

341*_*008 6 java spring dependency-injection inject

我有一个实现两个接口的 bean。准系统代码如下:

interface InterfaceA {
  ...
}

interface InterfaceB {
  ...
}

public class ClassC implements InterfaceA, InterfaceB {
  ...
}
Run Code Online (Sandbox Code Playgroud)

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

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

@Bean(name = "InterfaceB")
public InterfaceB interfaceB() {
    return new ClassC();
}
Run Code Online (Sandbox Code Playgroud)

我这样使用它:

public class MyClass {

    @Inject
    private final InterfaceA a;

    public MyClass(@Named("InterfaceA") InterfaceA a) {
        this.a = a;
    }
     ...
}
Run Code Online (Sandbox Code Playgroud)

然而,Spring 抱怨说:

未定义类型 [com.example.InterfaceA] 的合格 bean:预期有单个匹配 bean,但发现 2:InterfaceA、InterfaceB

类似的问题在这里被问到并回答了 EJB ,但我找不到 Spring beans 的任何内容。有人知道原因吗?

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

ade*_*nor 6

谢谢你提出了很好的问题。

就我而言,我创建了一个扩展 A 和 B 的接口:

public interface InterfaceC extends InterfaceA, InterfaceB {}
Run Code Online (Sandbox Code Playgroud)

...并且通用实现实现了统一的接口:

public class ClassC implements InterfaceC {
  //...
}
Run Code Online (Sandbox Code Playgroud)

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

@Bean
public InterfaceC implementationForAandB() {
    return new ClassC();
}
Run Code Online (Sandbox Code Playgroud)

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

public class MyClass {

    @Inject
    private final InterfaceA a;

    @Inject
    private final InterfaceB b;

    public MyClass(InterfaceA a, InterfaceB b) {
        //...
    }
Run Code Online (Sandbox Code Playgroud)

}


Ser*_*sta 4

春天来了……当你写作时

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

@Bean(name = "InterfaceB")
public InterfaceB interfaceB() {
    return new ClassC();
}
Run Code Online (Sandbox Code Playgroud)

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

然后当你写:

@Inject
private final InterfaceA a;
Run Code Online (Sandbox Code Playgroud)

你要求Spring找到一个bean实现 InterfaceA,但正如上面所说,有2个这样的错误。

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

@Inject
@Named("InterfaceA")
private final InterfaceA a;
Run Code Online (Sandbox Code Playgroud)

这样,您明确要求 Spring 查找名为 的 InterfaceAbean ,并希望它现在是唯一的。