且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

如何注入实现同一接口的两个不同类的两个实例?

更新时间:2023-11-22 16:30:52

为了注入不同的实例,有不同的方法来构造和注入bean.

In order to inject different instances, there are different ways to construct and inject beans.

方法1 :

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

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

这些限定符可用于您的施工参数注入或setter注入级别的班级部分.

These qualifiers can be used in your class part of construction parameter injection or setter injection level.

@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

Approach 2: Use of @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来生成接口.这种机制会很有效,因为它在注入bean的地方使用了InjectionPoint.

Above custom qualifiers will allow you to chose type of implementation by removing abibuaty in producer method. And, you can use below mentioned MyClassFactory to produce interfaces. This mechanism would be efficient as it uses InjectionPoint where the bean is injected.

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();
    }
}

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

Finally, you can use these generated instances in your class.

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 ...
}