gpt4 book ai didi

java - 如何注入(inject)实现相同接口(interface)的两个不同类的两个实例?

转载 作者:行者123 更新时间:2023-12-02 01:33:36 24 4
gpt4 key购买 nike

在java中处理CDI时,我想注入(inject)两个不同类的两个实例,实现相同的接口(interface)。

据我了解,我可以注入(inject)不实现接口(interface)的类的实例,例如:

class MyClass {
// ...
}

class XY {
@Inject MyClass myClass;
}

当我的类实现一个接口(interface)时,我必须通过接口(interface)名称声明成员(并指定具体实现):

class MyClass implements MyInterface {
// ...
}

class XY {
@Inject MyInterface myClass;
}

但是一旦我想注入(inject)不同的实现,我就会收到“Api 类型 [...] 未通过限定符找到”异常:

class MyClassOne implements MyInterface {
// ...
}

class MyClassTwo implements MyInterface {
// ...
}

class XY {
@Inject MyClassOne myClassOne;
@Inject MyClassTwo myClassTwo;
}

我很欣赏任何尝试什么或在哪里继续阅读的想法(有关此主题的搜索的明显关键字会给出非常不具体的结果)。提前致谢!

最佳答案

为了注入(inject)不同的实例,有不同的方式来构造和注入(inject)bean。

方法 1:

@Qualifier
@Retention(RUNTIME)
@Target({FIELD, TYPE, METHOD})
public @interface ClassifierOne {
}

@Qualifier
@Retention(RUNTIME)
@Target({FIELD, TYPE, METHOD})
public @interface ClassifierTwo {
}

这些限定符可以在构造参数注入(inject)或 setter 注入(inject)级别的类部分中使用。

@ClassifierOne
public class MyClassOne implements MyInterface {
// ...
}

@ClassifierTwo
public class MyClassTwo implements MyInterface {
// ...
}

public class XY {
private final MyInterface myClassOne;
private final MyInterface myClassTwo;

@Inject
public XY ( @ClassifierOne MyInterface myClassOne, @ClassifierTwo MyInterface myClassTwo ) {
this.myClassOne = myClassOne;
this.myClassTwo = myClassTwo;
}
}

方法 2:使用 @Produces

@Qualifier
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.TYPE, ElementType.METHOD})
public @interface MyClassType {
ClassImplName value();
}

public enum ClassImplName {
CLASS_ONE(MyClassOne.class),
CLASS_TWO(MyClassTwo.class);

private Class<? extends MyInterface> classType;

private ClassImplName(Class<? extends MyInterface> clazz) {
this.classType = clazz;
}

public Class<? extends MyInterface> getClassType(){
return classType;
}
}

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.METHOD, ElementType.TYPE})
public @interface ClassType {
ClassImplName value();
}

上面的自定义限定符将允许您通过删除生产者方法中的 abibuaty 来选择实现类型。并且,您可以使用下面提到的 MyClassFactory 来生成接口(interface)。这种机制非常高效,因为它使用注入(inject) Bean 的 InjectionPoint。

public class MyInterfaceFactory {

@Produces
@MyClassType
public MyInterface createMyClasses(@Any Instance<MyInterface> instance, InjectionPoint injectionPoint) {
Annotated annotated = injectionPoint.getAnnotated();
ClassType classTypeAnnotation = annotated.getAnnotation(ClassType.class);
Class<? extends MyInterface> classType = classTypeAnnotation.value().getClassType();
return instance.select(classType).get();
}
}

最后,您可以在您的类中使用这些生成的实例。

public class XY {

@Inject
@ClassType(ClassImplName.CLASS_ONE)
@MyClassType
private MyInterface myClassOne;

@Inject
@ClassType(ClassImplName.CLASS_TWO)
@MyClassType
private MyInterface myClassTwo;

// Other methods using injected beans ...
}

关于java - 如何注入(inject)实现相同接口(interface)的两个不同类的两个实例?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55618095/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com