【问题标题】:how to create multiple instance of same type using google Guice如何使用 google Guice 创建多个相同类型的实例
【发布时间】:2019-04-02 03:54:11
【问题描述】:

我们使用 Google Guice 框架进行依赖注入。我需要在java中创建一个接口的多个实例。

从这里开始执行:下面代码中的KfhRecordValidator.java类:

public class KfhRecordValidator implements RequestHandler<Request, Response> {
       public Response handleRequest(Request request, Context context) 
        {
     // Resolve the necessary dependencies, and process the request.
       Injector injector = Guice.createInjector(new 
                      DependencyModule());
            Processor processor = 
                 injector.getInstance(Processor.class);
              return processor.process(request, context);
}}

流程类引用了 RecordValidationHelper 类,并且注入是通过构造函数进行的。 IRecordValidationService.java 是一个具有 validate 方法的接口。

public interface IRecordValidationService {
              void validate(Record record) throws ValidationException;}

类处理器有一个名为 process 的方法,该方法在 RecordValidationHelper 类中被调用。

class Processor {
   private final RecordValidationHelper recordValidationHelper;
@Inject
@SuppressWarnings({"WeakerAccess"})
public Processor(IRecordValidationService recordValidationService, 
IRecordService<ErrorRecord> recordService,
                 S3UtilsInterface s3Utils, IEnvironmentVariableReader 
                 environmentVariableReader) {
                 this.recordValidationHelper = new 
                 RecordValidationHelper(recordValidationService);
                 this.errorRecordHelper = new 
                 ErrorRecordHelper(recordService, environmentVariableReader);
}

public Response process(Request request, @SuppressWarnings("unused") Context context) {

    // Validate records
    List<LambdaRecord> records = recordValidationHelper.processRecords(request.getRecords());}

Class DependencyModule.java extneds 具有配置方法的 Guice 注入的 AbstractModule 类。

class DependencyModule extends AbstractModule {
@Override
protected void configure() {
    String validationType = System.getenv("ValidationType");

    validationType= validationType.toLowerCase(Locale.ENGLISH);

    String valType[]= validationType.split(",");
    int length= valType.length;

    for(int i=0;i<length;i++){

        switch(valType[i]){
         case "json":
             bind(IRecordValidationService.class).to(JsonValidationService.class);
             break;
         case "avro":
             bind(IRecordValidationService.class).to(AvroSchemaValidationService.class);
             break;
         case "clientlogging":
             bind(IRecordValidationService.class).to(ClientLoggingValidationService.class);
             break;
         case "servicelogs":
             bind(IRecordValidationService.class).to(ServiceLoggingValidationService.class);
             break;
         default:
             throw new UnsupportedOperationException(String.format("Encountered an unsupported ValidationType of '%s'.", valType[i]));
        }

    } } }

所以问题是,如果我将验证类型设为 AVRO、JSON,那么它会将 IRecordValidationService 绑定到相应的 JsonValidationService/AvroSchemaValidationService 类。我需要为此创建多个实例,但它一次只支持一个实例。 下面是 RecordValidationHelper.java 类

公共类 RecordValidationHelper 扩展 AbstractModule { private final IRecordValidationService recordValidationService;

@Inject
public RecordValidationHelper(IRecordValidationService recordValidationService) {
    this.recordValidationService = recordValidationService;
}

public List processRecords(List requestRecords) { 列出记录 = new ArrayList();

    for (RequestRecord record : requestRecords) {
        try {

            Record domainRecord = new Record();
            domainRecord.setKey(record.getRecordId());
            domainRecord.setValue(new String(Base64.getDecoder().decode(record.getData())));

            // Use the injected logic to validate the record.
            ((IRecordValidationService) 
           recordValidationService).validate(domainRecord);}
           catch (ValidationException ex) {}}}
           return records;}

任何对如何实现它以获得适合此的多个实例有任何想法的人。

【问题讨论】:

    标签: java guice


    【解决方案1】:

    使用@Named 绑定

    在您的 DependencyModule 中,使用名称绑定:

    bind(IRecordValidationService.class)
      .annotatedWith(Names.named("json"))
      .to(JsonValidationService.class);
    bind(IRecordValidationService.class)
      .annotatedWith(Names.named("avro"))
      .to(AvroSchemaValidationService.class);
    bind(IRecordValidationService.class)
      .annotatedWith(Names.named("clientlogging"))
      .to(ClientLoggingValidationService.class);
    bind(IRecordValidationService.class)
      .annotatedWith(Names.named("servicelogs"))
      .to(ServiceLoggingValidationService.class);
    

    然后在你的被注射者中:

    @Inject
    public RecordValidationHelper(
        @Named("json") IRecordValidationService jsonValidation,
        @Named("avro") IRecordValidationService avroValidation,
        @Named("clientlogging") IRecordValidationService clientLoggingValidation,
        @Named("servicelogs") IRecordValidationService serviceLogsValidation,
      ) {
        this.jsonValidation = jsonValidation;
        this.avroValidation = avroValidation;
        this.clientLoggingValidation = clientLoggingValidation;
        this.serviceLogsValidation = serviceLogsValidation;
    }
    

    请参阅Guice's BindingAnnotation wiki page 了解更多信息。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-06-02
      • 1970-01-01
      • 2015-08-19
      • 2015-10-09
      • 1970-01-01
      • 2021-08-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多