ItemProcessor

ItemPorcessor๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€๊ณตํ•˜๊ฑฐ๋‚˜ ํ•„ํ„ฐ๋งํ•˜๋Š” ์—ญํ• ์„ ํ•˜๋ฉฐ, ํ•„์ˆ˜๊ฐ€ ์•„๋‹ˆ๋‹ค. ์ด ์—ญํ• ์€ ItemWriter์—์„œ๋„ ๊ตฌํ˜„์ด ๊ฐ€๋Šฅํ•˜์ง€๋งŒ, ๋ถ„๋ฆฌํ•จ์œผ๋กœ์จ ๋น„์ฆˆ๋‹ˆ์Šค ์ฝ”๋“œ๊ฐ€ ์„ž์ด๋Š” ๊ฒƒ์„ ๋ฐฉ์ง€ํ•  ์ˆ˜ ์žˆ๋‹ค.

public interface ItemProcessor<I, O> {
    @Nullable
    O process(@NonNull I var1) throws Exception;
}

I๋Š” ItemReader์—์„œ ๋ฐ›์„ ๋ฐ์ดํ„ฐ ํƒ€์ž…์ด๋ฉฐ, O๋Š” ItemWriter์— ๋ณด๋‚ผ ๋ฐ์ดํ„ฐ ํƒ€์ž…์ด๋‹ค. ์ฆ‰, Reader์—์„œ ์ฝ์€ ๋ฐ์ดํ„ฐ๊ฐ€ ItemProcessor์˜ process()๋ฅผ ํ†ต๊ณผํ•œ ํ›„ Writer์— ์ „๋‹ฌ๋œ๋‹ค. ๊ตฌํ˜„ํ•ด์•ผํ•  ๋ฉ”์†Œ๋“œ๋Š” processํ•˜๋‚˜์ด๋ฉฐ, Java 8๋ถ€ํ„ฐ๋Š” ์ธํ„ฐํŽ˜์ด์Šค์˜ ์ถ”์ƒ ๋ฉ”์„œ๋“œ๊ฐ€ 1๊ฐœ์ธ ๊ฒฝ์šฐ ๋žŒ๋‹ค์‹์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

@Bean(BEAN_PREFIX + "processor")
@StepScope
public ItemProcessor<ReadType, WriteType> processor() {
    return item -> {
        item.convert();
        return item;
    };
}
  • ๋ถˆํ•„์š”ํ•œ ์ฝ”๋“œ๊ฐ€ ์—†์–ด ๊ตฌํ˜„ ์ฝ”๋“œ ์–‘์ด ์ ๋‹ค. (๋น ๋ฅด๊ฒŒ ๊ตฌํ˜„ ๊ฐ€๋Šฅ)

  • ๊ณ ์ •๋œ ํ˜•ํƒœ๊ฐ€ ์—†์–ด ์›ํ•˜๋Š” ํ˜•ํƒœ์˜ ์–ด๋–ค ์ฒ˜๋ฆฌ๋„ ๊ฐ€๋Šฅํ•˜๋‹ค.

  • Batch Config ํด๋ž˜์Šค ์•ˆ์— ํฌํ•จ๋˜์–ด ์žˆ์–ด์•ผ๋งŒ ํ•˜๋ฉฐ, Batch Config ์ฝ”๋“œ ์–‘์ด ๋งŽ์•„์งˆ ์ˆ˜ ์žˆ๋‹ค.

    • ์ฝ”๋“œ ์–‘์ด ๋งŽ์•„์ง€๋งŒ ๋ณ„๋„ ํด๋ž˜์Šค๋กœ Processor๋ฅผ ๋ถ„๋ฆฌํ•ด์„œ ์‚ฌ์šฉํ•˜๊ธฐ๋„ ํ•œ๋‹ค.

ํฌ๊ฒŒ ItemProcessor๋Š” ๋‹ค์Œ ์—ญํ• ์„ ํ•œ๋‹ค.

  • ๋ณ€ํ™˜ : Reader์—์„œ ์ฝ์€ ๋ฐ์ดํ„ฐ๋ฅผ ์›ํ•˜๋Š” ํƒ€์ž…์œผ๋กœ ๋ณ€ํ™˜ํ•˜์—ฌ, Writer์— ๋„˜๊ฒจ์ค„ ์ˆ˜ ์žˆ๋‹ค.

  • ํ•„ํ„ฐ : Reader์—์„œ ๋„˜๊ฒจ์ค€ ๋ฐ์ดํ„ฐ๋ฅผ Writer๋กœ ๋„˜๊ฒจ์ค„ ๊ฒƒ์ธ์ง€ ๊ฒฐ์ •ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, null์„ ๋ฐ˜ํ™˜ํ•˜๋ฉด Writer์— ์ „๋‹ฌ๋˜์ง€ ์•Š๋Š”๋‹ค.

ItemProcessor๊ฐ€ null์„ ๋ฐ˜ํ™˜ํ•˜๋ฉด ํ•ด๋‹น Item์˜ ๋ชจ๋“  ์ดํ›„ ์ฒ˜๋ฆฌ๊ฐ€ ์ค‘์ง€๋œ๋‹ค. ์ด๋•Œ null์„ ๋ฐ˜ํ™˜ํ•˜๋”๋ผ๋„ ๋‹ค๋ฅธ Item ์ฒ˜๋ฆฌ๊ฐ€ ๊ณ„์† ์ด๋ฃจ์–ด์ง„๋‹ค.

๊ตฌํ˜„์ฒด

Spring Batch ์—์„œ๋Š” ์ž์ฃผ ์‚ฌ์šฉํ•˜๋Š” ์šฉ๋„์˜ Processor๋ฅผ ๋ฏธ๋ฆฌ ํด๋ž˜์Šค๋กœ ๋งŒ๋“ค์–ด์„œ ์ œ๊ณตํ•ด์ฃผ๊ณ  ์žˆ๋‹ค.

  • ItemProcessorAdapter

  • ValidatingItemProcessor

  • CompositeItemProcessor

ํ•˜์ง€๋งŒ ์ตœ๊ทผ์—๋Š” ๋Œ€๋ถ€๋ถ„ processor๋ฅผ ์ง์ ‘ ๊ตฌํ˜„ํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ๊ณ , ๋žŒ๋‹ค์‹์œผ๋กœ ๋น ๋ฅด๊ฒŒ ๊ตฌํ˜„ํ• ๋•Œ๋„ ๋งŽ๋‹ค. ๊ทธ๋ž˜์„œ ItemProcessorAdapter์™€ ValidatingItemProcessor๋Š” ๊ฑฐ์˜ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š”๋‹ค.

์ž…๋ ฅ ๋ฐ์ดํ„ฐ ์œ ํšจ์„ฑ ๊ฒ€์ฆ์— ์‚ฌ์šฉํ•˜๋Š” ItemProcessor ๊ตฌํ˜„์ฒด์ด๋‹ค. ์ž…๋ ฅ ์•„์ดํ…œ์˜ ์œ ํšจ์„ฑ ๊ฒ€์ฆ์„ ์ˆ˜ํ–‰ํ•˜๋Š” ์Šคํ”„๋ง๋ฐฐ์น˜ Validator๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์œ ํšจ์„ฑ ๊ฒ€์ฆ์ด ์‹คํŒจํ•˜๋ฉด, ValidationException์ด ๋ฐœ์ƒํ•œ๋‹ค.

  • org.springframework.batch.item.validator.ValidatingItemProcessor

BeanValidatingItemProcessor

JSR 303์€ ๋นˆ ์œ ํšจ์„ฑ ๊ฒ€์ฆ์„ ์œ„ํ•œ ๊ฒƒ์œผ๋กœ, ์Šคํ”„๋ง ๋ฐฐ์น˜๋Š” ๋ฏธ๋ฆฌ ์ •์˜๋œ ์œ ํšจ์„ฑ ๊ฒ€์ฆ ๊ธฐ๋Šฅ์„ ์–ด๋…ธํ…Œ์ด์…˜์œผ๋กœ ์ œ๊ณตํ•ด์ค€๋‹ค. ํ•ด๋‹น ์–ด๋…ธํ…Œ์ด์…˜์„ ์‚ฌ์šฉํ•˜๋ ค๋ฉด, ๋‹ค์Œ ์˜์กด์„ฑ์„ ์ถ”๊ฐ€ํ•ด์ค˜์•ผํ•œ๋‹ค.

์–ด๋…ธํ…Œ์ด์…˜
์†์„ฑ
์„ค๋ช…

@NotNull @Null

๊ฐ’์ด null์ธ์ง€ ์•„๋‹Œ์ง€ ๊ฒ€์‚ฌ

@Size

int min : ์ตœ์†Œ ํฌ๊ธฐ(default : 0) int max : ์ตœ๋Œ€ํฌ๊ธฐ

๊ธธ์ด๋‚˜ ํฌ๊ธฐ๊ฐ€ ์ง€์ •ํ•œ ๊ฐ’ ๋ฒ”์œ„์— ์žˆ๋Š”์ง€ ๊ฒ€์‚ฌ null์€ ์œ ํšจํ•˜๋‹ค๊ณ  ํŒ๋‹จ

@Pattern

String regexp = ์ •๊ทœํ‘œํ˜„์‹

๊ฐ’์ด ์ •๊ทœ ํ‘œํ˜„์‹์— ์ผ์น˜ํ•˜๋Š”์ง€ ๊ฒ€์‚ฌ null์€ ์œ ํšจํ•˜๋‹ค๊ณ  ํŒ๋‹จ

@AssertTrue @AssertFalse

๊ฐ’์ด true์ธ์ง€ false์ธ์ง€ ๊ฒ€์‚ฌ null์€ ์œ ํšจํ•˜๋‹ค ํŒ๋‹จ

@DecmialMax @DecimalMin

String value: ์ตœ๋Œ€๊ฐ’ ๋˜๋Š” ์ตœ์†Ÿ๊ฐ’ boolean inclusive : ์ง€์ •๊ฐ’ ํฌํ•จ ์—ฌ๋ถ€(default : true)

์ง€์ •ํ•œ ๊ฐ’๋ณด๋‹ค ์ž‘๊ฑฐ๋‚˜ ๊ฐ™์€์ง€ ํ˜น์€ ํฌ๊ฑฐ๋‚˜ ๊ฐ™์€์ง€ ๊ฒ€์‚ฌ null์€ ์œ ํšจํ•˜๋‹ค ํŒ๋‹จ

@Max @Min

long value

์ง€์ •ํ•œ ๊ฐ’๋ณด๋‹ค ์ž‘๊ฑฐ๋‚˜ ๊ฐ™์€์ง€ ํ˜น์€ ํฌ๊ฑฐ๋‚˜ ๊ฐ™์€์ง€ ๊ฒ€์‚ฌ null์€ ์œ ํšจํ•˜๋‹ค ํŒ๋‹จ

@Digits

int integer : ํ—ˆ์šฉ๊ฐ€๋Šฅํ•œ ์ •์ˆ˜ ์ž๋ฆฟ์ˆ˜ int fraction : ํ—ˆ์šฉ ๊ฐ€๋Šฅํ•œ ์†Œ์ˆ˜์  ์ดํ•˜ ์ž๋ฆฟ์ˆ˜

์ž๋ฆฟ์ˆ˜๊ฐ€ ์ง€์ •ํ•œ ํฌ๊ธฐ๋ฅผ ๋„˜์ง€ ์•Š๋Š”์ง€ ๊ฒ€์‚ฌ null์€ ์œ ํšจํ•˜๋‹ค ํŒ๋‹จ

@NotEmpty

๋ฌธ์ž์—ด, ๋ฐฐ์—ด : null์ด ์•„๋‹ˆ๊ณ , ๊ธธ์ด๊ฐ€ 0์ด ์•„๋‹Œ์ง€ ๊ฒ€์‚ฌ Collection : null์ด ์•„๋‹ˆ๊ณ , ํฌ๊ธฐ๊ฐ€ 0์ด ์•„๋‹Œ์ง€ ๊ฒ€์‚ฌ

@NotBlank

null์ด ์•„๋‹ˆ๊ณ  ์ตœ์†Œํ•œ ํ•œ๊ฐœ ์ด์ƒ์˜ ๊ณต๋ฐฑ์ด ์•„๋‹Œ ๋ฌธ์ž๋ฅผ ํฌํ•จํ•˜๋Š”์ง€ ๊ฒ€์‚ฌ

@Positive @PositiveOrZero

์–‘์ˆ˜์ธ์ง€ ๊ฒ€์‚ฌ OrZero๋Š” ์–‘์ˆ˜ ํ˜น์€ 0์ธ์ง€ ๊ฒ€์‚ฌ null์€ ์œ ํšจํ•˜๋‹ค ํŒ๋‹จ

@Negative @NegativeOrZero

์Œ์ˆ˜์ธ์ง€ ๊ฒ€์‚ฌ OrZero๋Š” ์Œ์ˆ˜ ํ˜น์€ 0์ธ์ง€ ๊ฒ€์‚ฌ null์€ ์œ ํšจํ•˜๋‹ค ํŒ๋‹จ

@Email

์ด๋ฉ”์ผ ์ฃผ์†Œ๊ฐ€ ์œ ํšจํ•œ์ง€ ๊ฒ€์‚ฌ null์€ ์œ ํšจํ•˜๋‹ค ํŒ๋‹จ

@Future @FuterOrPresent

ํ•ด๋‹น ์‹œ๊ฐ„์ด ๋ฏธ๋ž˜์ธ์ง€ ๊ฒ€์‚ฌ OrPresent๋Š” ํ˜„์žฌ ๋˜๋Š” ๋ฏธ๋ž˜์‹œ๊ฐ„์ธ์ง€ ๊ฒ€์‚ฌ null์€ ์œ ํšจํ•˜๋‹ค ํŒ๋‹จ

@Past @PastOrPresent

ํ•ด๋‹น ์‹œ๊ฐ„์ด ๊ณผ๊ฑฐ์ธ์ง€ ๊ฒ€์‚ฌ OrPresent๋Š” ํ˜„์žฌ ๋˜๋Š” ๊ณผ๊ฑฐ์‹œ๊ฐ„์ธ์ง€ ๊ฒ€์‚ฌ null์€ ์œ ํšจํ•˜๋‹ค ํŒ๋‹จ

์œ„ ์˜ˆ์ œ์™€ ๊ฐ™์ด ๊ณ ์œ ํ•œ ๋ฉ”์„ธ์ง€๋ฅผ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ํ•„๋“œ ๊ฐ’์˜ ๊ธธ์ด๊ฐ€ ์ž˜๋ชป๋๋Š”์ง€ ํ˜•์‹์ด ์ž˜๋ชป๋๋Š”์ง€ ์‹๋ณ„ํ•  ์ˆ˜ ์žˆ๋‹ค.

๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ง€์ •ํ•œ validation์— ๋งž์ง€ ์•Š์œผ๋ฉด ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

ValidatingItemProcessor

๋ฐ์ดํ„ฐ์…‹ ๋‚ด์—์„œ ํ•œ๊ฐœ์˜ ํ•„๋“œ์˜ ๊ฐ’์ด ๊ณ ์œ ํ•ด์•ผํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ์žˆ์„ ์ˆ˜ ์žˆ๋‹ค. ๊ณ ์œ ํ•œ ๊ฐ’์˜ ํ•„๋“œ๋ฅผ ItemStream ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•˜์—ฌ, ๊ฐ ์ปค๋ฐ‹๊ณผ ํ•„๋“œ ๊ฐ’์„ ExecutionContext์— ์ €์žฅํ•ด ์ƒํƒœ๋ฅผ ์œ ์ง€ํ•  ์ˆ˜ ์žˆ๋‹ค.

Validator๋ฅผ ๊ตฌํ˜„ํ•œ ํ›„ Step์„ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๊ตฌํ˜„ํ•˜๋ฉด ๋œ๋‹ค.

ItemProcessorAdapter

  • org.springframework.batch.item.adapter.ItemProcessorAdapter

์„œ๋น„์Šค๋ฅผ ItemProcessor ์—ญํ• ์„ ํ•˜๋„๋ก ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค.

๊ณ ๊ฐ์˜ ์ด๋ฆ„์„ ๋Œ€๋ฌธ์ž๋กœ ๋ฐ”๊ฟ”์ฃผ๋Š” ์„œ๋น„์Šค์ด๋‹ค. ์ด ์„œ๋น„์Šค๋ฅผ ItemProcessorAdapter๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ Processor๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

ScriptItemProcessor

Ruby, JavaScript, Groovy ๋“ฑ ๋‹ค์–‘ํ•œ ์Šคํฌ๋ฆฝํŠธ ์–ธ์–ด๋ฅผ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค.

  • org.springframework.batch.item.support.ScriptItemProcessor

์ˆ˜ํ–‰ํ•˜๊ณ  ์‹ถ์€ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋ฐ”์ธ๋”ฉํ•˜์—ฌ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

CompositeItemProcessor

https://media.springernature.com/original/springer-static/image/chp%3A10.1007%2F978-1-4842-3724-3_8/MediaObjects/215885_2_En_8_Fig1_HTML.png

CompositeItemProcessor๋Š” ItemProcessor๊ฐ„์˜ ์ฒด์ด๋‹์„ ์ง€์›ํ•˜๋Š” Processor์ด๋‹ค.

๋‹ค์Œ๊ณผ ๊ฐ™์ด Processor๊ฐ€ ์—ฌ๋Ÿฌ๊ฐœ ํ•„์š”ํ•œ ๊ฒฝ์šฐ ์ฒด์ด๋‹ ์ž‘์—…์„ ํ•  ์ˆ˜ ์žˆ๋‹ค.

ํ•˜์ง€๋งŒ, ์—ฌ๊ธฐ์„œ ์ œ๋„ค๋ฆญ ํƒ€์ž…์€ ์‚ฌ์šฉํ•˜์ง€ ๋ชปํ•˜๋ฉฐ, ๋งŒ์•ฝ ์ œ๋„ค๋ฆญํƒ€์ž…์„ ์‚ฌ์šฉํ•˜๊ฒŒ ๋˜๋ฉด delegates์— ํฌํ•จ๋œ ItemProcessor๋Š” ๋ชจ๋‘ ๊ฐ™์€ ์ œ๋„ค๋ฆญ ํƒ€์ž…์„ ๊ฐ€์ ธ์•ผํ•œ๋‹ค. ๋งŒ์•ฝ ๊ฐ™์€ ์ œ๋„ค๋ฆญ ํƒ€์ž…์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ItemProcessor๊ฐ„ ์ฒด์ด๋‹์ด๋ผ๋ฉด ์ œ๋„ค๋ฆญ์„ ์„ ์–ธํ•˜๋Š” ๊ฒƒ์ด ๋” ์•ˆ์ „ํ•œ ์ฝ”๋“œ๊ฐ€ ๋  ์ˆ˜ ์žˆ๋‹ค.

ClassifierCompositeItemProcessor

  • org.springframework.batch.item.support.ClassifierCompositeItemProcessor

Classifier ๊ตฌํ˜„์ฒด๋กœ ์‚ฌ์šฉํ•  ItemProcessor๋ฅผ ์„ ์ •ํ•ด classify ๋ฉ”์„œ๋“œ๋ฅผ ์ˆ˜ํ–‰ํ•ด ๋ถ„๋ฅ˜ ์ฒ˜๋ฆฌ๋ฅผ ํ•  ์ˆ˜ ์žˆ๋‹ค.

๋‹ค์Œ์€ ์šฐํŽธ๋ฒˆํ˜ธ๋ฅผ ์ง์ˆ˜ ํ™€์ˆ˜๋กœ ๋ถ„๋ฅ˜ํ•œ Classifier ๊ตฌํ˜„์ฒด์ด๋‹ค.

๊ตฌํ˜„ํ•œ Classifier๋ฅผ ClassifierCompositeItemProcessor๋กœ ๊ตฌํ˜„ํ•˜์—ฌ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค.

ํ™€์ˆ˜์ธ ๊ฒฝ์šฐ์—๋Š” upperCase์ถœ๋ ฅ, ์ง์ˆ˜์ธ ๊ฒฝ์šฐ lowerCase๋กœ ๋ถ„๋ฅ˜ํ•ด์„œ ์ถœ๋ ฅํ•˜๋„๋ก ๊ตฌํ˜„ํ•˜์˜€์œผ๋ฉฐ, ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ •์ƒ์ ์œผ๋กœ ์ถœ๋ ฅ๋˜๋Š”๊ฑธ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

ItemProcessor ์ง์ ‘ ๊ตฌํ˜„ํ•˜๊ธฐ

์ปค์Šคํ…€ ํ”„๋กœ์„ธ์„œ๋ฅผ ์ƒ์„ฑํ•˜์—ฌ ์ง์ˆ˜ ์šฐํŽธ๋ฒˆํ˜ธ๋Š” ํ•„ํ„ฐ๋งํ•˜๊ณ  ํ™€์ˆ˜ ์šฐํŽธ๋ฒˆํ˜ธ๋งŒ ๋‚จ๊ฒจ๋‘๋Š” ItemProcessor ์˜ˆ์ œ๋ฅผ ์‚ดํŽด๋ณผ ๊ฒƒ์ด๋‹ค.

ItemProcessor๋Š” **null**์„ ๋ฐ˜ํ™˜ํ•˜๋ฉด ํ•ด๋‹น ์•„์ดํ…œ์€ ๊ทธ ์ดํ›„ ์ˆ˜ํ–‰๋˜๋Š” ItemProcessor๋‚˜ ItemWriter๋กœ ์ „๋‹ฌ๋˜์ง€ ์•Š๊ณ , ํ•„ํ„ฐ๋ง๋œ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•„ํ„ฐ๋ง๋œ ๋ ˆ์ฝ”๋“œ์˜ ์ˆ˜๋ฅผ JobRepository์— ๊ด€๋ฆฌํ•˜๊ณ  ์žˆ๋‹ค.

๋‹ค์Œ๊ณผ ๊ฐ™์ด ItemProcessor๋ฅผ ๊ตฌํ˜„ํ•˜์—ฌ, process ๋ฉ”์„œ๋“œ์— ์›ํ•˜๋Š” ๋กœ์ง์„ ์ž‘์„ฑํ•ด์ฃผ๋ฉด ๋œ๋‹ค.

BATCH_STEP_EXECUTION ๋‚ด์— ์„ฑ๊ณตํ•œ ์ˆ˜, ํ•„ํ„ฐ๋ง ๊ฑธ๋ฆฐ ์•„์ดํ…œ ์ˆ˜๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

image-20211203232101096

์ฐธ๊ณ 

Last updated

Was this helpful?