Использование фабричного шаблона в Spring Batch FileHeaderFieldSetMapper - PullRequest
0 голосов
/ 04 ноября 2018

Я устанавливаю задание Spring Batch, которое будет обрабатывать файл с несколькими записями. Одна из записей имеет следующую структуру.

Ind,RecCode,AccNum,RecTypeDesc,EffectiveDate,CreditAmount,DebitAmount,BatchNumber,NumberOfTrasactions 
5, 20, 100, prl, 12084, as0, 0, 3, 1

В зависимости от значения в поле RecordCode это будет либо запись платежа, либо запись сторнирования.

Я настраиваю PatternMatchingCompositeLineMapper для чтения типов записей в файле. Я создал следующие 2 реализации классов FieldSetMapper

@Component("paymentBatchFieldSetMapper")
public class  PaymentBatchFieldSetMapper implements FieldSetMapper<PaymentBatch> {

    @Override
    public PaymentBatch mapFieldSet(FieldSet fieldSet) throws BindException {
        // TODO Auto-generated method stub
        return null;
    }
}

и второй как,

@Component("reversalBatchFieldSetMapper")
public class  ReversalBatchFieldSetMapper implements FieldSetMapper<PaymentBatch> {

    @Override
    public PaymentBatch mapFieldSet(FieldSet fieldSet) throws BindException {
        // TODO Auto-generated method stub
        return null;
    }
}

Я создал фабричный класс как следующий, чтобы возвратить любой из 2 выше как ниже

@Component("achBatchFieldSetMapperFactory")
public class ACHBatchFieldSetMapperFactory {

    @Autowired
    private ApplicationContext applicationContext;

    public FieldSetMapper<? extends AbstractACHBatch> getFieldSetMapper(RecordTypeDescription recordTypeDescription) {
        FieldSetMapper<? extends AbstractACHBatch> fieldSetMapper = null;
        switch(recordTypeDescription) {
        case PAYMENT:
            fieldSetMapper = applicationContext.getBean(PaymentBatchFieldSetMapper.class);
            break;
        case REVERSAL:
            fieldSetMapper = applicationContext.getBean(ReversalBatchFieldSetMapper.class);
            break;
        }
        return fieldSetMapper;
    }
}

Ниже приведена конфигурация bean-компонента для объекта карты, который нужно внедрить в PatternMatchingCompositeLineMapper.

@Bean
public Map<String, LineTokenizer> fieldSetMapperMap(FileHeaderFieldSetMapper fileHeaderFieldSetMapper, PaymentBatchFieldSetMapper paymentBatchFieldSetMapper,
        ReversalBatchFieldSetMapper reversalBatchFieldSetMapper) {
    Map<String, FieldSetMapper> map = new HashMap<String, FieldSetMapper>();
    map.put("1*", fileHeaderFieldSetMapper);
    map.put("5*", ?????);                   
}

Есть ли вероятность, что я смогу использовать фабрику для возврата необходимого преобразователя FieldSet в зависимости от записи в файле?

1 Ответ

0 голосов
/ 05 ноября 2018

Считыватель предметов предназначен для одновременного возврата одного типа предметов. Давайте представим, что нам удается отобразить записи либо в PaymentBatch, либо в ReversalBatch в соответствии с полем RecordCode, это означает, что после сопоставления ItemReader вернет два типа. Это невозможно по замыслу.

Что вы можете сделать, это создать POJO, который имеет взаимно-однозначное сопоставление с полями во входном файле, а затем использовать ClassifierCompositeItemProcessor для обработки каждого элемента в соответствии с его типом (классификатор будет основан на RecordTypeDescription enum в вашем случае).

NB: Конечно, технически возможно забыть об универсальном типе интерфейса ItemReader<T> и заставить считыватель элементов вернуть Object s, но это потребует уродливого использования instanceof в вашем процессоре, чтобы определить тип записи. Я настоятельно рекомендую , а не , используя этот подход.

...