Programming/Spring Framework 주요 개념

데이터 바인딩 추상화 (스프링 핵심 기술 - 3)

흠냐아뤼 2020. 3. 4. 23:17
728x90

 

데이터 바인딩이란?

- 기술적인 관점 : 프로퍼티 값을 타겟 객체에 설정하는 기능

- 사용자 관점 : 사용자 입력 값을 애플리케이션 도메인 모델에 동적으로 변환해 넣어주는 기능

즉, 입력 값은 대부분 '문자열'인데, 그 값을 객체가 가지고 있는 int, long, Boolean, Date 등 심지어 Event, Book 같은 도메인 타입으로도 변환해서 넣어주는 기능

 

 

1. PropertyEditor

- getValue, setValue 에서의 Value는 Property가 가지고 있는 값인데, 서로 다른 쓰레드에게 공유됨 (상태정보를 저장하고 있음, Thread Safe 하지 않음)

따라서, PropertyEditor의 구현체들은 여러 스레드에 공유해서 사용하면 안됨. (빈으로 등록해서 사용하면 안됨)

          -> @InitBinder를 사용하여 컨트롤러에 등록

- Object와 String 간의 변환만 할 수 있어, 상당히 제한적임

이와 같은 단점들로 인해 다음의 개선된 방법을 사용

 

 

2. Converter

- S 타입을 T 타입으로 변환할 수 있는 매우 일반적인 변환기

- 상태 정보 없음 == Stateless == Thread Safe (빈으로 등록하여 사용 가능)

- ConverterRegistry에 등록해서 사용

public class EventConverter {

    public static class StringToEventConverter implements Converter<String, Event> {

        @Override
        public Event convert(String s) {
            return new Event(Integer.parseInt(s));
        }
    }

    public static class EventToStringConverter implements Converter<Event, String> {

        @Override
        public String convert(Event event) {
            return event.getId().toString();
        }
    }
}

 

 

3.  Formatter 

- Obj와 String간의 변환을 담당

- 웹쪽으로 특화되어 있는 인터페이스 (문자열을 Locale에 따라 다국화하는 기능을 제공)

- 이것도 Thread Safe

- FormatterRegister에 등록해서 사용

public class EventFormatter implements Formatter<Event> {

    @Override
    public Event parse(String s, Locale locale) throws ParseException {
        return new Event(Integer.parseInt(s));
    }

    @Override
    public String print(Event event, Locale locale) {
        return event.getId().toString();
    }
}

 

 

4. ConversionService

- 실제 변환 작업은 이 인터페이스를 통해서 Thread Safe하게 사용할 수 있음

 

(Spring Boot를 사용하는 경우)

- Web MVC 설정 필요 없이 스프링 부트가 Converter, Formatter 설정을 자동으로 해줌

- 이때, 해당 클래스는 빈으로 등록되어 있어야 함

public class EventConverter {

    @Component
    public static class StringToEventConverter implements Converter<String, Event> {
        @Override
        public Event convert(String s) {
            return new Event(Integer.parseInt(s));
        }
    }

    @Component
    public static class EventToStringConverter implements Converter<Event, String> {
        @Override
        public String convert(Event event) {
            return event.getId().toString();
        }
    }
}

 

@Component
public class EventFormatter implements Formatter<Event> {

    @Override
    public Event parse(String s, Locale locale) throws ParseException {
        return new Event(Integer.parseInt(s));
    }

    @Override
    public String print(Event event, Locale locale) {
        return event.getId().toString();
    }
}

 

Formattor를 사용하는 방법을 추천

왜? 보통은 데이터 바인딩을 만들 때 웹과 관련해서 만들기 때문에

 

 

인프런 백기선님 '스프링 핵심 기술' 강의를 듣고 정리한 내용입니다.
728x90