We have used Google Guice framework for dependency injection. I need to create multiple insatnce of an interface in java.
The execution starts from here: KfhRecordValidator.java class in the below code:
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);
}}
The process class is having reference of RecordValidationHelper class and the injection is through constructor. IRecordValidationService.java is an interface that is having validate method.
public interface IRecordValidationService {
void validate(Record record) throws ValidationException;}
class processor is having one method called process that is being called in RecordValidationHelper class.
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 AbstractModule class of Guice injection that is having configure method.
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]));
}
} } }
SO the issue is if I am getting validation type as AVRO, JSON then it will bind IRecordValidationService to respective JsonValidationService/AvroSchemaValidationService class. I need to create multiple instance for that but it supports only once instance at a time. Below is the RecordValidationHelper.java class
public class RecordValidationHelper extends AbstractModule { private final IRecordValidationService recordValidationService;
@Inject
public RecordValidationHelper(IRecordValidationService recordValidationService) {
this.recordValidationService = recordValidationService;
}
public List processRecords(List requestRecords) { List records = 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;}
Anyone having any idea about how it should be implemented to get multiple instance suitable for this.
@Named
bindings In your DependencyModule
, bind using names:
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);
Then in your injectee:
@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;
}
See Guice's BindingAnnotation wiki page for more info.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.