๐Ÿ“š
TIL
  • README
  • Git
    • Basic
    • Remote Repository
    • Log & Diff
    • Rebase&Cherri-Pick
    • git-flow
  • DevOps
    • Monolithic vs MSA
    • Jenkins ์‹œ์ž‘ํ•˜๊ธฐ
    • Airflow ์‹œ์ž‘ํ•˜๊ธฐ
    • Airflow ์‹œ์ž‘ํ•˜๊ธฐ
    • Build Tools
      • maven
  • ๊ฐœ๋ฐœ ๋ฐฉ๋ฒ•๋ก 
    • TDD
  • Spring
    • IoC
    • Is Spring Bean Thread-Safe?
    • Spring Singleton
    • Component Scan
    • Spring Annotation
    • ์˜์กด ๊ด€๊ณ„ ์ฃผ์ž…(DI)
    • Lombok ํ™œ์šฉํ•˜๊ธฐ
    • Bean ์ƒ๋ช…์ฃผ๊ธฐ์™€ ์ฝœ๋ฐฑ
    • Bean Scope
    • AOP(1) - AOP๋ž€
    • AOP(2) - Aop Proxy
    • AOP(3) - Dynamic Proxy
    • AOP(4) - AspectJ
    • POJO
    • Spring ์„œ๋น„์Šค ๊ตฌ์กฐ
    • Transaction
    • JPA๋ž€?
    • JPA Entity
    • Spring Data JPA
    • Spring Data Specification
    • Model Mapping
    • Cache
    • restTemplate
    • YAML ํŒŒ์ผ ์„ค์ •
    • Spring Boot
      • H2 DB ์„ค์ •
      • ๋‹ค์ค‘ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์„ค์ •
      • Mybatis ์—ฐ๋™ํ•˜๊ธฐ
    • Spring Batch
      • Batch ์‹œ์ž‘ํ•ด๋ณด๊ธฐ
      • Batch Job Flow
      • Job
      • Step
      • Batch Scope & Job Parameter
      • JobRepository์™€ ๋ฉ”ํƒ€ํ…Œ์ด๋ธ”
      • Chunk ์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ
      • ItemReader
      • ItemProcessor
      • ItemWriter
      • Batch Schedular
      • Job๋ณ„ Bean๋“ฑ๋กํ•˜๊ธฐ
      • Batch ๊ตฌํ˜„์‹œ ๋ฐœ์ƒํ•œ ์˜ค๋ฅ˜ ์ •๋ฆฌ
      • Spring Batch Scaling
        • Multithread Job๊ตฌํ˜„์‹œ ์ด์Šˆ์‚ฌํ•ญ
    • Spring test
      • Junit5
        • ํ…Œ์ŠคํŠธ ์ด๋ฆ„ ํ‘œ๊ธฐ
        • ํ…Œ์ŠคํŠธ ๊ทธ๋ฃน ์‚ฌ์ด์˜ ๊ด€๊ณ„
        • ํƒœ๊ทธ์™€ ํ•„ํ„ฐ๋ง
        • ๋™์  ํ…Œ์ŠคํŠธ
        • ํ…Œ์ŠคํŠธ LifeCycle
        • ํ…Œ์ŠคํŠธ ๋ฉ”์„œ๋“œ
        • ํ…Œ์ŠคํŠธ ์ˆœ์„œ
        • AssertJ
        • ํ…Œ์ŠคํŠธ ๋ณ‘๋ ฌ ์‹คํ–‰
        • AssertJ
        • Mock
      • Spring Boot Test DB ๋ถ„๋ฆฌ
      • Spring Batch Test
  • Web Application
    • Web Server & WAS
    • ๊ด€๋ จ ๊ฐœ๋… - HTTP API, HTML, CSR, SSR
    • Servlet
    • JSP
    • Cookie And Session
    • ์˜ˆ์™ธํŽ˜์ด์ง€
    • Java Bean
    • JDBC
    • Connection Pool
    • ํŒŒ์ผ ์—…๋กœ๋“œ
    • Expression Language
    • JSTL
    • FrontControllerํŒจํ„ด Command ํŒจํ„ด
    • Forwarding
    • MVC
    • ํšŒ์›๊ฐ€์ž…์˜ˆ์ œ
    • ์ฐธ๊ณ 
      • ๊ฐœ๋ฐœํ™˜๊ฒฝ์„ค์ •
  • Java+
    • SOAP/WSDL vs REST
    • WSDL์„ JAVA๋กœ ๋ณ€ํ™˜ํ•˜๊ธฐ
    • SOAP ํ†ต์‹  OPEN API๋กœ ๊ฐœ๋ฐœํ•ด๋ณด๊ธฐ
  • Java
    • Basic
      • ๋ณ€์ˆ˜์™€ ํƒ€์ž…
      • ์—ฐ์‚ฐ์ž
      • ์กฐ๊ฑด๋ฌธ๊ณผ ๋ฐ˜๋ณต๋ฌธ
      • ์ฐธ์กฐ ํƒ€์ž…
      • ํด๋ž˜์Šค
      • ์ƒ์†(Inheritance)
      • ์ธํ„ฐํŽ˜์ด์Šค(Interface)
      • ์ค‘์ฒฉ ํด๋ž˜์Šค์™€ ์ค‘์ฒฉ ์ธํ„ฐํŽ˜์ด์Šค
      • ์˜ˆ์™ธ ์ฒ˜๋ฆฌ
      • API - Object, System, Class, Math, Wrapper
      • API - String, StringBuffer, StringBuilder
      • Thread
      • Generic
      • Lambda
      • Collection - List, Set
      • Collection - Map
      • Collection - Tree
      • Collection - Stack, Queue
      • Stream
      • Reflection
      • ์ •๊ทœํ‘œํ˜„์‹
      • GUI
      • UML
      • Serializable
    • Advanced
      • OutOfMemoryError
      • AutoValue
      • meta-annotation
        • @Retention
        • @Target
        • @Repeatable
    • Effective Java 3/E
      • ITEM 1: Static Factory Method(์ •์  ๋ฉ”์†Œ๋“œ)
      • ITEM 2: Builder Pattern
      • ITEM 3: Singleton
      • ITEM 4: Private Constructor
      • ITEM 5: Dependency Injection
      • ITEM 6: Avoid Unnecessary Object
      • ITEM 7: Eliminate Object Reference
      • ITEM 8: Avoid finalizer and cleaner
      • ITEM 9: try-with-resources
      • ITEM 10: The gerneral contract when overriding equlas
      • ITEM 11: Overriding hashCode
      • ITEM 12: overriding toString
      • ITEM 13: overriding clone judiciously
      • ITEM 14: Consider implementing comparable
      • ITEM 15: ํด๋ž˜์Šค์™€ ๋ฉค๋ฒ„์˜ ์ ‘๊ทผ์„ ์ตœ์†Œํ™”ํ•ด๋ผ
      • ITEM 16: Use Accessor methods
      • ITEM 17: ๋ณ€๊ฒฝ ๊ฐ€๋Šฅ์„ฑ์„ ์ตœ์†Œํ™”ํ•ด๋ผ(๋ถˆ๋ณ€ ํด๋ž˜์Šค)
      • ITEM 18: ์ƒ์†๋ณด๋‹จ ์ปดํฌ์ง€์…˜์„ ์‚ฌ์šฉํ•ด๋ผ
      • ITEM 19: ์ƒ์†์„ ๊ณ ๋ คํ•ด ์„ค๊ณ„ํ•˜๊ณ  ๋ฌธ์„œํ™”ํ•ด๋ผ
      • ITEM 20: ์ถ”์ƒ ํด๋ž˜์Šค๋ณด๋‹ค ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์šฐ์„ ํ•˜๋ผ
      • ITEM 21: ์ธํ„ฐํŽ˜์ด์Šค๋Š” ๊ตฌํ˜„ํ•˜๋Š” ์ชฝ์„ ์ƒ๊ฐํ•ด ์„ค๊ณ„ํ•ด๋ผ.
      • ITEM 22: ์ธํ„ฐํŽ˜์ด์Šค๋Š” ํƒ€์ž…์„ ์ •์˜ํ•˜๋Š” ์šฉ๋„๋กœ๋งŒ ์‚ฌ์šฉํ•ด๋ผ
      • ITEM 23: ํƒœ๊ทธ ๋‹ฌ๋ฆฐ ํด๋ž˜์Šค๋ณด๋‹ค ํด๋ž˜์Šค ๊ณ„์ธต๊ตฌ์กฐ๋ฅผ ํ™œ์šฉํ•ด๋ผ
      • ITEM 24: ๋ฉค๋ฒ„ ํด๋ž˜์Šค๋Š” ๋˜๋„๋ก static์œผ๋กœ ๊ตฌํ˜„ํ•ด๋ผ
      • ITEM 25: ํ†ฑ๋ ˆ๋ฒจ ํด๋ž˜์Šค๋Š” ํ•œ ํŒŒ์ผ์— ํ•˜๋‚˜๋งŒ ์ƒ์„ฑํ•ด๋ผ.
      • ITEM 26: Raw type์€ ์‚ฌ์šฉํ•˜์ง€ ๋งˆ๋ผ
      • ITEM 27: ๋น„๊ฒ€์‚ฌ ๊ฒฝ๊ณ ๋ฅผ ์ œ๊ฑฐํ•ด๋ผ
      • ITEM 28: ๋ฐฐ์—ด๋ณด๋‹ค๋Š” ๋ฆฌ์ŠคํŠธ๋ฅผ ์‚ฌ์šฉํ•ด๋ผ
      • ITEM 29: ์ด์™•์ด๋ฉด ์ œ๋„ค๋ฆญ ํƒ€์ž…์œผ๋กœ ๋งŒ๋“ค์–ด๋ผ
      • ITEM 30: ์ด์™•์ด๋ฉด ์ œ๋„ค๋ฆญ ๋ฉ”์„œ๋“œ๋กœ ๋งŒ๋“ค์–ด๋ผ
      • ITEM 31 : ํ•œ์ •์  ์™€์ผ๋“œ์นด๋“œ๋ฅผ ์‚ฌ์šฉํ•ด API ์œ ์—ฐ์„ฑ์„ ๋†’์—ฌ๋ผ
      • ITEM 32: ์ œ๋„ค๋ฆญ๊ณผ ๊ฐ€๋ณ€์ธ์ˆ˜๋ฅผ ํ•จ๊ป˜ ์“ธ ๋•Œ๋Š” ์‹ ์ค‘ํ•ด๋ผ
      • ITEM 33: ํƒ€์ž… ์•ˆ์ „ ์ด์ข… ์ปจํ…Œ์ด๋„ˆ๋ฅผ ๊ณ ๋ คํ•ด๋ผ
      • ITEM 34: int ์ƒ์ˆ˜ ๋Œ€์‹  ์—ด๊ฑฐ ํƒ€์ž…์„ ์‚ฌ์šฉํ•ด๋ผ
      • ITEM 35: ordinal ๋ฉ”์„œ๋“œ ๋Œ€์‹  ์ธ์Šคํ„ด์Šค ํ•„๋“œ๋ฅผ ์‚ฌ์šฉํ•ด๋ผ
      • ITEM 36: ๋น„ํŠธ ํ•„๋“œ ๋Œ€์‹  EnumSet์„ ์‚ฌ์šฉํ•ด๋ผ
      • ITEM 37: ordinal ์ธ๋ฑ์‹ฑ ๋Œ€์‹  EnumMap์„ ์‚ฌ์šฉํ•ด๋ผ
      • TEM 38 : ํ™•์žฅํ•  ์ˆ˜ ์žˆ๋Š” ์—ด๊ฑฐํƒ€์ž…์ด ํ•„์š”ํ•˜๋ฉด ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์‚ฌ์šฉํ•ด๋ผ
      • ITEM 39: ๋ช…๋ช… ํŒจํ„ด๋ณด๋‹ค ์• ๋„ˆํ…Œ์ด์…˜์„ ์‚ฌ์šฉํ•ด๋ผ
      • ITEM 40: @Override ์–ด๋…ธํ…Œ์ด์…˜์„ ์ผ๊ด€๋˜๊ฒŒ ์‚ฌ์šฉํ•ด๋ผ
      • ITEM 41: ์ •์˜ํ•˜๋ ค๋Š” ๊ฒƒ์ด ํƒ€์ž…์ด๋ผ๋ฉด ๋งˆ์ปค ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์‚ฌ์šฉํ•ด๋ผ
      • ITEM 42: ์ต๋ช… ํด๋ž˜์Šค๋ณด๋‹ค๋Š” ๋žŒ๋‹ค๋ฅผ ์‚ฌ์šฉํ•ด๋ผ
      • ITEM 43: ๋žŒ๋‹ค๋ณด๋‹ค๋Š” ๋ฉ”์„œ๋“œ ์ฐธ์กฐ๋ฅผ ์‚ฌ์šฉํ•ด๋ผ
      • ITEM 44: ํ‘œ์ค€ ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์‚ฌ์šฉํ•ด๋ผ
      • ITEM 45: ์ŠคํŠธ๋ฆผ์€ ์ฃผ์˜ํ•ด์„œ ์‚ฌ์šฉํ•ด๋ผ
      • ITEM 46: ์ŠคํŠธ๋ฆผ์—์„œ ๋ถ€์ž‘์šฉ ์—†๋Š” ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ด๋ผ
      • ITEM 47: ๋ฐ˜ํ™˜ ํƒ€์ž…์œผ๋กœ๋Š” ์ŠคํŠธ๋ฆผ๋ณด๋‹ค ์ปฌ๋ ‰์…˜์ด ๋‚ซ๋‹ค.
      • ITEM 48: ์ŠคํŠธ๋ฆผ ๋ณ‘๋ ฌํ™”๋Š” ์ฃผ์˜ํ•ด์„œ ์‚ฌ์šฉํ•ด๋ผ
      • ITEM 49: ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ์œ ํšจํ•œ์ง€ ๊ฒ€์‚ฌํ•ด๋ผ
      • ITEM 50: ์ ์‹œ์— ๋ฐฉ์–ด์  ๋ณต์‚ฌ๋ณธ์„ ๋งŒ๋“ค์–ด๋ผ
      • ITEM 51: ๋ฉ”์„œ๋“œ ์‹œ๊ทธ๋‹ˆ์ฒ˜๋ฅผ ์‹ ์ค‘ํžˆ ์„ค๊ณ„ํ•ด๋ผ
      • ITEM 52: ๋‹ค์ค‘์ •์˜๋Š” ์‹ ์ค‘ํžˆ ์‚ฌ์šฉํ•ด๋ผ
      • ITEM 53: ๊ฐ€๋ณ€์ธ์ˆ˜๋Š” ์‹ ์ค‘ํžˆ ์‚ฌ์šฉํ•ด๋ผ
      • ITEM 54: null์ด ์•„๋‹Œ, ๋นˆ ์ปฌ๋ ‰์…˜์ด๋‚˜ ๋ฐฐ์—ด์„ ๋ฐ˜ํ™˜ํ•ด๋ผ
      • ITEM 55: Optional ๋ฐ˜ํ™˜์€ ์‹ ์ค‘ํ•˜๊ฒŒ ํ•ด๋ผ
      • ITEM 56: ๊ณต๊ฐœ๋œ API ์š”์†Œ์—๋Š” ํ•ญ์ƒ ์ฃผ์„์„ ์ž‘์„ฑํ•ด๋ผ
      • ITEM 57: ์ง€์—ญ๋ณ€์ˆ˜์˜ ๋ฒ”์œ„๋ฅผ ์ตœ์†Œํ™”ํ•ด๋ผ
      • ITEM 58: ์ „ํ†ต์ ์ธ for ๋ฌธ๋ณด๋‹ค๋Š” for-each๋ฌธ์„ ์‚ฌ์šฉํ•ด๋ผ
      • ITEM 59: ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์ตํžˆ๊ณ  ์‚ฌ์šฉํ•ด๋ผ
      • ITEM 60: ์ •ํ™•ํ•œ ๋‹ต์ด ํ•„์š”ํ•˜๋‹ค๋ฉด float์™€ double์€ ํ”ผํ•ด๋ผ
      • ITEM 61: ๋ฐ•์‹ฑ๋œ ๊ธฐ๋ณธ ํƒ€์ž…๋ณด๋‹ค๋Š” ๊ธฐ๋ณธ ํƒ€์ž…์„ ์‚ฌ์šฉํ•ด๋ผ
      • ITEM 62: ๋‹ค๋ฅธ ํƒ€์ž…์ด ์ ์ ˆํ•˜๋‹ค๋ฉด ๋ฌธ์ž์—ด ์‚ฌ์šฉ์„ ํ”ผํ•ด๋ผ
      • ITEM 63: ๋ฌธ์ž์—ด ์—ฐ๊ฒฐ์€ ๋А๋ฆฌ๋‹ˆ ์ฃผ์˜ํ•ด๋ผ
      • ITEM 64: ๊ฐ์ฒด๋Š” ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์‚ฌ์šฉํ•ด ์ฐธ์กฐํ•ด๋ผ
      • ITEM 65: ๋ฆฌํ”Œ๋ ‰์…˜๋ณด๋‹ค๋Š” ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์‚ฌ์šฉํ•ด๋ผ
      • ITEM 66: ๋„ค์ดํ‹ฐ๋ธŒ ๋ฉ”์„œ๋“œ๋Š” ์‹ ์ค‘ํžˆ ์‚ฌ์šฉํ•ด๋ผ
      • ITEM 67: ์ตœ์ ํ™”๋Š” ์‹ ์ค‘ํžˆ ํ•ด๋ผ
      • ITEM 68: ์ผ๋ฐ˜์ ์œผ๋กœ ํ†ต์šฉ๋˜๋Š” ๋ช…๋ช… ๊ทœ์น™์„ ๋”ฐ๋ผ๋ผ
    • ๊ฐ์ฒด์ง€ํ–ฅ ์„ค๊ณ„ ์›์น™(SOLID)
    • ๋””์ž์ธํŒจํ„ด
      • Strategy Pattern
      • Template Method Pattern
      • Factory Method Pattern
      • Singleton
      • Delegation
      • Proxy
      • Adapter Pattern
    • ์‹ค์Šต
      • ์ธํ„ฐํŽ˜์ด์Šค ์‹ค์Šต - Vehicle
      • ์ธํ„ฐํŽ˜์ด์Šค ์‹ค์Šต - Remote
      • GUI ์‹ค์Šต - Calculator
      • GUI ์‹ค์Šต - button
      • GUI ์‹ค์Šต - lotto
      • Thread ์‹ค์Šต - ์ขŒ์„์˜ˆ์•ฝ, ๋ฉ”์„ธ์ง€๋ณด๋‚ด๊ธฐ
    • Jar vs War
  • ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค
    • KEY
    • Index
    • Transaction
    • Trigger
    • Procedure / Function
    • Package
    • ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๋ฐฐ์›€ํ„ฐ
      • ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์‹œ์Šคํ…œ
      • ๊ด€๊ณ„๋ฐ์ดํ„ฐ ๋ชจ๋ธ
      • ๊ด€๊ณ„๋Œ€์ˆ˜์™€ SQL
    • MySQL
      • Database๋ž€
      • MySQL ์‹œ์ž‘ํ•˜๊ธฐ
      • MySQL Database
      • MySQL Table
      • CRUD
      • ๊ด€๊ณ„ํ˜• ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค
      • Server์™€ Client
    • PostgreSQL
    • NoSQL
      • Install Cassandra on mac
      • Cassandra๋ž€?
      • NiFi๋ž€
  • Algorithm
    • String
    • Recursion
    • Dynamic Programming
    • Array, Struct, Pointer
    • Math
    • Sort
    • List
    • Stack
    • Queue
    • Graph
    • Tree
    • Maze
    • AVL
    • ์ด์ง„ํƒ์ƒ‰ํŠธ๋ฆฌ(Binary Search Tree)
    • DFS์™€ BFS
    • ๋‹ค์ต์ŠคํŠธ๋ผ ์•Œ๊ณ ๋ฆฌ์ฆ˜(Dijkstra's Algorithm)
    • Red-Black ํŠธ๋ฆฌ
    • A* ์•Œ๊ณ ๋ฆฌ์ฆ˜
    • Heap
    • Huffman Coding
    • Priority Queue
    • Bellman-Ford ์•Œ๊ณ ๋ฆฌ์ฆ˜
    • C++
      • Class
      • STL
        • STL pair
        • STL Container - Associate Container
        • STL Container - Sequence Container
        • STL Container - Container Adapter
  • JavaScript
    • JABASCRIPT BASIC
    • Shallow Copy vs Deep Copy
    • OBJECT MODEL
    • NODE
    • ๋™๊ธฐ ์ฒ˜๋ฆฌ vs ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ
    • AJAX
    • CALLBACK
    • PROMISE
    • DEFERRER
    • UNDERSCORE
    • WEBPACK
    • SCOPE
    • EXECUTION CONTEXT
    • Image Object
    • BFCache๋ž€?
    • history.scrollRestoration
    • Intersection Observer
    • JWT - JSON Web Token
    • HTML vs JSON
  • Vue.js
    • ํ™˜๊ฒฝ์„ค์ •
    • Vue.js๋ž€?
    • Vue Instance
    • Vue Component
    • Vue Router
    • HTTP ํ†ต์‹ 
    • Template
    • Single File Component
    • Vue Animation
    • Vuex
    • Djnago์™€ ์—ฐ๋™ํ•˜๊ธฐ
  • Backbone.js
    • Model
    • Collection
    • Sync
    • view
  • Node.js
    • Doit! - ๋…ธ๋“œ๋กœ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋Š” ๋Œ€ํ‘œ์ ์ธ ์„œ๋ฒ„์™€ ์šฉ๋„
    • Doit! - ๋…ธ๋“œ์— ๋Œ€ํ•ด ์•Œ์•„๋ณด๊ณ  ๊ฐœ๋ฐœ ๋„๊ตฌ ์„ค์น˜ํ•˜๊ธฐ
    • Doit! - ๋…ธ๋“œ ๊ฐ„๋‹จํ•˜๊ฒŒ ์‚ดํŽด๋ณด๊ธฐ
    • Doit! - ๋…ธ๋“œ์˜ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์™€ ์นœํ•ด์ง€๊ธฐ
    • Doit! - ๋…ธ๋“œ์˜ ๊ธฐ๋ณธ ๊ธฐ๋Šฅ ์•Œ์•„๋ณด๊ธฐ
    • Doit! - ์›น ์„œ๋ฒ„ ๋งŒ๋“ค๊ธฐ
    • Doit! - ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์‚ฌ์šฉํ•˜๊ธฐ
    • Doit! - ์ต์Šคํ”„๋ ˆ์Šค ํ”„๋กœ์ ํŠธ๋ฅผ ๋ชจ๋“ˆํ™”ํ•˜๊ธฐ
    • Doit! - ๋ทฐ ํ…œํ”Œ๋ฆฟ ์ ์šฉํ•˜๊ธฐ
    • Doit! - ํŒจ์ŠคํฌํŠธ๋กœ ์‚ฌ์šฉ์ž ์ธ์ฆํ•˜๊ธฐ
    • Doit! - ์ฑ„ํŒ…์„œ๋ฒ„ ๋งŒ๋“ค๊ธฐ
    • Doit! - JSON-RPC ์„œ๋ฒ„ ๋งŒ๋“ค๊ธฐ
  • Python
    • Warning-Could not import the lzma module
    • Pandas
      • Pandas ์ž๋ฃŒ๊ตฌ์กฐ
      • Pandas ๋ฐ์ดํ„ฐ ์ž…์ถœ๋ ฅ
      • DataFrame Data ์‚ดํŽด๋ณด๊ธฐ
      • ์‹œ๊ฐํ™” ๋„๊ตฌ - Matplotlib
  • ML
    • ์ถ”์ฒœ ์‹œ์Šคํ…œ
      • Collaborative Filtering
      • Matrix Factorization
  • Django
    • Basic
      • ํ™˜๊ฒฝ์„ค์ •
      • About Django
      • Start Django Project
      • Secret Key ๊ด€๋ฆฌํ•˜๊ธฐ
      • Settings ๋ถ„๋ฆฌํ•˜๊ธฐ
      • Django App
      • Django View & URL (1)
      • Django Model
        • MySQL ์—ฐ๋™
      • Django Admin
      • Django View & URL (2)
      • Django Template
      • Django Template & View & URL
      • Django Static
      • Django form
    • Advanced
      • Django Generic View
      • Django Automated Testing
      • Django Extenstion Template
      • Django Model Package
      • Django OpenSSL setting
    • REST framework
      • Rest API
      • Serializers
      • ViewSet
    • Error
      • ํ™˜๊ฒฝ์„ค์ • zlib ์˜ค๋ฅ˜๋ฐœ์ƒ
      • ModuleNotFoundError
    • ํŒจํ‚ค์ง€
      • django-debug-toolbar
    • Vue.js ์—ฐ๋™ํ•˜๊ธฐ
  • Ruby
    • variable & input/output
    • ์กฐ๊ฑด๋ฌธ
    • ๋ฐ˜๋ณต๋ฌธ
    • Array & Hash
    • Method
    • Proc&Lamda
    • Class
  • Ruby on Rails
    • Scaffolding
    • Controller
    • Model
    • Model-M:N relation
    • Model Validation
    • ๋ฉ‹์‚ฌ 10์ฃผ์ฐจ ์ˆ˜์—…(Tip)
  • HTML/CSS
    • Udacity - Intro to HTML/CSS
    • Udacity - Responsive Web Design
    • Udacity - Responsive Images
    • HTML Basic
    • CSS Basic
    • HTML5 Sementic Tag
    • HTML ํ…์ŠคํŠธ ๊ด€๋ จ ํƒœ๊ทธ๋“ค
    • HTML5 ๋ฉ€ํ‹ฐ๋ฏธ๋””์–ด
    • HTML ํผ ๊ด€๋ จ ํƒœ๊ทธ๋“ค
    • ํ…์ŠคํŠธ ๊ด€๋ จ ์Šคํƒ€์ผ
    • ์ƒ‰์ƒ๊ณผ ๋ฐฐ๊ฒฝ์„ ์œ„ํ•œ ์Šคํƒ€์ผ
    • ๋ ˆ์ด์•„์›ƒ์„ ์œ„ํ•œ ์Šคํƒ€์ผ
    • CSS ํฌ์ง€์…”๋‹
    • ๋‹ค์žฌ๋‹ค๋Šฅํ•œ CSS3 ์„ ํƒ์ž
    • CSS์™€ ์• ๋‹ˆ๋ฉ”์ด์…˜
    • ๋ฐ˜์‘ํ˜• ์›น์ด๋ž€?
  • OS(์šด์˜์ฒด์ œ)
    • Linux
      • Daemon
      • Cron
      • ํ”„๋กœ์„ธ์Šค ๊ด€๋ จ ๋ช…๋ น์–ด
      • ํ…์ŠคํŠธ ํŒŒ์ผ ๋ช…๋ น์–ด
  • Network
    • ๋„คํŠธ์›Œํฌ ๊ธฐ๋ณธ ๊ฐœ๋…
    • ๋„คํŠธ์›Œํฌ ๊ธฐ๋ณธ ๊ทœ์น™
    • ๋ฌผ๋ฆฌ ๊ณ„์ธต
    • ๋ฐ์ดํ„ฐ ๋งํฌ ๊ณ„์ธต
    • ๋„คํŠธ์›Œํฌ ๊ณ„์ธต
    • ์ „์†ก ๊ณ„์ธต
    • ์‘์šฉ ๊ณ„์ธต
    • ๋„คํŠธ์›Œํฌ ์ „์ฒด ํ๋ฆ„
    • ๋ฌด์„  ๋žœ
  • IT ๊ธฐํƒ€์ง€์‹
    • NAS๋ž€
Powered by GitBook
On this page
  • ๊ตฌํ˜„์ฒด
  • BeanValidatingItemProcessor
  • ValidatingItemProcessor
  • ItemProcessorAdapter
  • ScriptItemProcessor
  • CompositeItemProcessor
  • ClassifierCompositeItemProcessor
  • ItemProcessor ์ง์ ‘ ๊ตฌํ˜„ํ•˜๊ธฐ
  • ์ฐธ๊ณ 

Was this helpful?

  1. Spring
  2. Spring Batch

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์— ๋„˜๊ฒจ์ค„ ์ˆ˜ ์žˆ๋‹ค.

    		// Pay -> String ํƒ€์ž… ๋ณ€ํ™˜
    		@Bean
        public ItemProcessor<Pay, String> processor(){
            return pay -> {
                return pay.getTxName();
            };
        }
  • ํ•„ํ„ฐ : Reader์—์„œ ๋„˜๊ฒจ์ค€ ๋ฐ์ดํ„ฐ๋ฅผ Writer๋กœ ๋„˜๊ฒจ์ค„ ๊ฒƒ์ธ์ง€ ๊ฒฐ์ •ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, null์„ ๋ฐ˜ํ™˜ํ•˜๋ฉด Writer์— ์ „๋‹ฌ๋˜์ง€ ์•Š๋Š”๋‹ค.

    		// amount๊ฐ€ 10000์ด์ƒ์ธ ๊ฐ’๋งŒ Writer์— ๋„˜์–ด๊ฐ€๋„๋ก ํ•„ํ„ฐ
    		@Bean
        public ItemProcessor<Pay, Pay> nullProcessor(){
            return pay -> {
                if(pay.getAmount() < 10000){
                    log.info("Pay amount :{}", pay.getAmount());
                    return null;
                }
                return pay;
            };
        }

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

implementation 'org.springframework.boot:spring-boot-starter-validation'
์–ด๋…ธํ…Œ์ด์…˜
์†์„ฑ
์„ค๋ช…

@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์€ ์œ ํšจํ•˜๋‹ค ํŒ๋‹จ

public class Customer {

    @NotNull(message = "firstname์€ ํ•„์ˆ˜๊ฐ’์ž…๋‹ˆ๋‹ค.")
    @Pattern(regexp = "[a-zA-Z]+", message = "firstname์€ ์˜์–ด์—ฌ์•ผํ•ฉ๋‹ˆ๋‹ค.")
    private String firstName;

    @NotNull(message = "city ํ•„์ˆ˜๊ฐ’์ž…๋‹ˆ๋‹ค.")
    @Pattern(regexp = "[a-zA-Z\\. ]+")
    private String city;

    @NotNull(message = "state ํ•„์ˆ˜๊ฐ’์ž…๋‹ˆ๋‹ค.")
    @Size(min=2, max=2)
    @Pattern(regexp = "[A-Z{2}]+")
    private String state;

  // ...
}

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

    @Bean
    public Step validationDelimitedFileStep() {
        return this.stepBuilderFactory.get("validationDelimitedFileStep")
                .<Customer, Customer>chunk(10)
                .reader(validationDelimitedCustomerItemReader(null))
                .processor(validationCustomerProcessor()) // processor
                .writer(validationDelimitedCustomerItemWriter())
                .build();
    }

    /**
     * BeanValidationItemProcessor ์„ค์ •
     * @return
     */
    @Bean
    public BeanValidatingItemProcessor<Customer> validationCustomerProcessor() {
        return new BeanValidatingItemProcessor<>();
    }
Field error in object 'item' on field 'middleInitial': rejected value [YS]; codes [Size.item.middleInitial,Size.middleInitial,Size.java.lang.String,Size]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [item.middleInitial,middleInitial]; arguments []; default message [middleInitial],1,1]; default message [ํฌ๊ธฐ๊ฐ€ 1์—์„œ 1 ์‚ฌ์ด์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค]
Field error in object 'item' on field 'middleInitial': rejected value [YS]; codes [Pattern.item.middleInitial,Pattern.middleInitial,Pattern.java.lang.String,Pattern]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [item.middleInitial,middleInitial]; arguments []; default message [middleInitial],[Ljavax.validation.constraints.Pattern$Flag;@5c7a06ec,[a-zA-Z]]; default message [middleInitial๋Š” ๋ฐ˜๋“œ์‹œ ์˜์–ด์—ฌ์•ผํ•ฉ๋‹ˆ๋‹ค.]

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

ValidatingItemProcessor

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

/**
 * JobExecution ๊ฐ„์˜ ์ƒํƒœ๋ฅผ ์ €์žฅํ•˜๊ธฐ ์œ„ํ•ด ItemStreamSupport ์ƒ์†
 */
public class UniqueLastNameValidator extends ItemStreamSupport implements Validator<Customer> {

    private Set<String> lastNames = new HashSet<>();

    @Override
    public void validate(Customer value) throws ValidationException {
        if (lastNames.contains(value.getLastName())) {
            throw new ValidationException(value.getLastName() + " lastName์ด ์ค‘๋ณต๋ฉ๋‹ˆ๋‹ค.");
        }
        this.lastNames.add(value.getLastName());
    }

    @Override
    public void open(ExecutionContext executionContext) {

        String lastNames = getExecutionContextKey("lastNames");

        // lastNames๊ฐ€ Execution์— ์ €์žฅ๋˜์–ด์žˆ๋Š”์ง€ ํ™•์ธ ํ›„ ์ €์žฅ๋˜์–ด์žˆ๋‹ค๋ฉด, ์Šคํ… ์ฒ˜๋ฆฌ ์ด์ „์— ํ•ด๋‹น๊ฐ’์œผ๋กœ ์›๋ณต
        if (executionContext.containsKey(lastNames)) {
            this.lastNames = (Set<String>) executionContext.get(lastNames);
        }
    }

    /**
     * ์ฒญํฌ ๋‹จ์œ„๋กœ ์ˆ˜ํ–‰๋˜๋Š”๋ฐ, ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•  ๊ฒฝ์šฐ ํ˜„์žฌ ์ƒํƒœ๋ฅผ ExecutionContext์— ์ €์žฅ
     * @param executionContext
     */
    @Override
    public void update(ExecutionContext executionContext) {
        Iterator<String> itr = lastNames.iterator();
        Set<String> copiedLastNames = new HashSet<>();

        while (itr.hasNext()) {
            copiedLastNames.add(itr.next());
        }

        executionContext.put(getExecutionContextKey("lastNames"), copiedLastNames);
    }
}

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

@Bean
    public Step validationDelimitedFileStep() {
        return this.stepBuilderFactory.get("validationDelimitedFileStep")
                .<Customer, Customer>chunk(10)
                .reader(validationDelimitedCustomerItemReader(null))
                .processor(customerValidatingItemProcessor()) // ํ”„๋กœ์„ธ์„œ
                .writer(validationDelimitedCustomerItemWriter())
                .stream(uniqueLastNameValidator()) // stream ์„ค์ •
                .build();
    }



    @Bean
    public ValidatingItemProcessor<Customer> customerValidatingItemProcessor() {
        return new ValidatingItemProcessor<>(uniqueLastNameValidator());
    }

    @Bean
    public UniqueLastNameValidator uniqueLastNameValidator() {
        UniqueLastNameValidator uniqueLastNameValidator = new UniqueLastNameValidator();

        uniqueLastNameValidator.setName("uniqueLastNameValidator");

        return uniqueLastNameValidator;
    }

ItemProcessorAdapter

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

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

@Service
public class UpperCaseNameService {
    public Customer upperCase(Customer customer) {

        Customer newCustomer = new Customer(customer);

        newCustomer.setFirstName(newCustomer.getFirstName().toUpperCase());
        newCustomer.setLastName(newCustomer.getLastName().toUpperCase());
        newCustomer.setMiddleInitial(newCustomer.getMiddleInitial().toUpperCase());

        return newCustomer;
    }
}

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

@Bean
public Step validationDelimitedFileStep() {
  	return this.stepBuilderFactory.get("validationDelimitedFileStep")
                .<Customer, Customer>chunk(10)
                .reader(validationDelimitedCustomerItemReader(null))
                .processor(customerItemProcessorAdapter())
                .writer(validationDelimitedCustomerItemWriter())
                .stream(uniqueLastNameValidator())
                .build();
}


@Bean
public ItemProcessorAdapter<Customer, Customer> customerItemProcessorAdapter() {
		ItemProcessorAdapter<Customer, Customer> adapter = new ItemProcessorAdapter<>();
    adapter.setTargetObject(upperCaseNameService);
    adapter.setTargetMethod("upperCase");
    return adapter;
}

ScriptItemProcessor

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

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

// lowerCase.js
item.setFirstName(item.getFirstName().toLowerCase());
item;
@Bean
@StepScope
public ScriptItemProcessor<Customer, Customer> scriptItemProcessor(@Value("#{jobParameters['script']}") Resource script) {
  	ScriptItemProcessor<Customer, Customer> itemProcessor = new ScriptItemProcessor<>();

    itemProcessor.setScript(script);

    return itemProcessor;
}

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

CompositeItemProcessor

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

    @Bean
    public CompositeItemProcessor compositeItemProcessor(){
        List<ItemProcessor> delegates = new ArrayList<>(2);
        delegates.add(nullProcessor());
        delegates.add(processor());

        CompositeItemProcessor processor = new CompositeItemProcessor();
        processor.setDelegates(delegates);
        return processor;
    }

		@Bean
    public ItemProcessor<Pay, String> processor(){
        return pay -> {
            return pay.getTxName();
        };
    }


    @Bean
    public ItemProcessor<Pay, Pay> nullProcessor(){
        return pay -> {
            if(pay.getAmount() < 10000){
                log.info("Pay amount :{}", pay.getAmount());
                return null;
            }
            return pay;
        };
    }

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

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

ClassifierCompositeItemProcessor

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

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

public interface Classifier<C, T> extends Serializable {

	T classify(C classifiable);

}

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

@AllArgsConstructor
public class ZipCodeClassifier implements Classifier<Customer, ItemProcessor<Customer, Customer>> {

    private ItemProcessor<Customer, Customer> oddProcessor;
    private ItemProcessor<Customer, Customer> evenProcessor;


    @Override
    public ItemProcessor<Customer, Customer> classify(Customer classifiable) {
        if (Integer.parseInt(classifiable.getZipCode()) % 2 == 0) {
            return evenProcessor;
        } else {
            return oddProcessor;
        }
    }
}

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

		// ํ™€์ˆ˜, ์ง์ˆ˜ ํ”„๋กœ์„ธ์„œ ์„ค์ •
		@Bean
    public Classifier classifier() {
        return new ZipCodeClassifier(customerItemProcessorAdapter(), scriptItemProcessor());
    }

    @Bean
    public ClassifierCompositeItemProcessor<Customer, Customer> classifierCompositeItemProcessor() {
        ClassifierCompositeItemProcessor<Customer, Customer> itemProcessor = new ClassifierCompositeItemProcessor<>();
        itemProcessor.setClassifier(classifier());
        return itemProcessor;
    }

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

Customer(firstName=aimee, middleInitial=C, lastName=Hoover, addressNumber=7341, street=Vel Avenue, city=Mobile, state=AL, zipCode=35928, address=null, transactions=null)
Customer(firstName=JONAS, middleInitial=U, lastName=GILBERT, addressNumber=8852, street=In St., city=Saint Paul, state=MN, zipCode=57321, address=null, transactions=null)
Customer(firstName=REGAN, middleInitial=M, lastName=BAXTER, addressNumber=4851, street=Nec Av., city=Gulfport, state=MS, zipCode=33193, address=null, transactions=null)
Customer(firstName=OCTAVIUS, middleInitial=T, lastName=DAUGHERTY, addressNumber=7418, street=Cum Road, city=Houston, state=TX, zipCode=51507, address=null, transactions=null)
Customer(firstName=stuart, middleInitial=K, lastName=Mckenzie, addressNumber=5529, street=Orci Av., city=Nampa, state=ID, zipCode=18562, address=null, transactions=null)
Customer(firstName=PETRA, middleInitial=Z, lastName=LARA, addressNumber=8401, street=Et St., city=Georgia, state=GA, zipCode=70323, address=null, transactions=null)
Customer(firstName=cherokee, middleInitial=T, lastName=Laradd, addressNumber=8516, street=Mauris St., city=Seattle, state=WA, zipCode=28720, address=null, transactions=null)
Customer(firstName=athena, middleInitial=Y, lastName=Burt, addressNumber=4951, street=Mollis Rd., city=Newark, state=DE, zipCode=41034, address=null, transactions=null)
Customer(firstName=kaitlin, middleInitial=M, lastName=Macias, addressNumber=5715, street=Velit St., city=Chandler, state=AZ, zipCode=86176, address=null, transactions=null)
Customer(firstName=LEROY, middleInitial=X, lastName=CHERRY, addressNumber=7810, street=Vulputate St., city=Seattle, state=WA, zipCode=37703, address=null, transactions=null)

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

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

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

public class EvenFilteringItemProcessor implements ItemProcessor<Customer, Customer> {
    @Override
    public Customer process(Customer item) throws Exception {
        return Integer.parseInt(item.getZipCode()) % 2 == 0 ? null : item;
    }
}

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

SELECT	STEP_EXECUTION_ID AS ID, STEP_NAME, COMMIT_COUNT, READ_COUNT, FILTER_COUNT, WRITE_COUNT
FROM		BATCH_STEP_EXECUTION;

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

์ฐธ๊ณ 

PreviousItemReaderNextItemWriter

Last updated 3 years ago

Was this helpful?

๊ธฐ์–ต๋ณด๋‹จ ๊ธฐ๋ก์„ - 9. Spring Batch ๊ฐ€์ด๋“œ - ItemProcessor
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
image-20211203232101096