데이터 바인딩 추상화: Converter와 Formatter - KwangtaekJung/inflearn-spring-framework-essential GitHub Wiki

  1. 데이터 바인딩 추상화: Converter와 Formatter
    PropertyEditro의 단점을 보완하기 위해 나온 인터페이스
  • S 타입을 T 타입으로 변환할 수 있는 매우 일반적인 변환기.
  • 상태 정보 없음 == Stateless == 쓰레드세이프 => Bean으로 등록해서 사용해도 상관없음.
  • ConverterRegistry에 등록해서 사용
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 EventToString implements Converter<Event, String> {
        @Override
        public String convert(Event event) {
            return event.getId().toString();
        }
    }
}
@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Override
    public void addFormatters(FormatterRegistry registry) {
        registry.addConverter(new EventConverter.StringToEventConverter());
    }
}

Integer 등의 기본 타입은 별도의 Converter나 Formatter를 등록하지 않아도 된다. 기본적인 것들은 스프링이 이미 다 등록해 주고 있다.

  • PropertyEditor 대체제
  • General한 변환을 하는 Converter에 비해 Object와 String 간의 변환을 담당한다.
    웹 환경에서는 String <-> Object 간의 변환 케이스가 매우 빈번하다.
  • 문자열을 Locale에 따라 다국화하는 기능도 제공한다. (optional) => MessageSource 부분 참고할 것!!
    PropertyEditor와 마찬가지로 String <-> Object간의 변환이라는 것은 같지만 Locale 기반이라는 차이가 있다.
  • FormatterRegistry에 등록해서 사용
//@Component // 직접 빈으로 등록해서 사용 가능함.
public class EventFormatter implements Formatter<Event> {
  @Override
  public Event parse(String text, Locale locale) throws ParseException {
    Event event = new Event();
    int id = Integer.parseInt(text);
    event.setId(id);
    return event;
  }

  @Override
  public String print(Event object, Locale locale) {
    return object.getId().toString();
  }
 }
  • 실제 변환 작업은 이 인터페이스를 통해서 쓰레드-세이프하게 사용할 수 있음.
  • 스프링 MVC, 빈 (value) 설정, SpEL에서 사용한다.
    위의 예제들은 스프링 MVC에서 사용되는 예를 보여준다.
  • DefaultFormattingConversionService
    => ConverService의 구현체 중 하나로써 @Autowired해서 주입받는 구현체로 주로 사용된다. 하지만....
    • FormatterRegistry
    • ConversionService
    • 여러 기본 컴버터와 포매터 등록 해 줌.

예제처럼 스프링 MVC에서 자동으로 사용되어지는 것이 아니라,
우리가 직접 컨버팅을 수행해야 한다면 ConversionService를 주입받아서 사용하면 된다.
하지만 이렇게 직접 주입받아서 사용하는 경우는 실제로는 거의 없을 것이다.

image

@Component
public class AppRunner implements ApplicationRunner {

    @Autowired
    ConversionService conversionService;

    @Override
    public void run(ApplicationArguments args) throws Exception {
        System.out.println(conversionService);  // 등록된 모든 컨버터를 보여준다.
        System.out.println(conversionService.getClass().toString());
    }
}

스프링 부트

  • 웹 애플리케이션인 경우에 DefaultFormattingConversionSerivce를 상속하여 만든 WebConversionService를 빈으로 등록해 준다.
    그래서 더 많은 기능을 가지고 있고 ConversionService를 주입받으면 WebConversionService가 나온다.
  • Formatter와 Converter 빈을 찾아 자동으로 등록해 준다.
    @Component를 사용해 빈으로만 만들어주면 예제처럼 @Configuration안에서 registry.addConverter 로 직접 등록해줄 필요가 없음. 컨버터 빈은 컨버터로 포매터 빈은 포매터로 자동으로 등록해 준다.
⚠️ **GitHub.com Fallback** ⚠️