데이터 바인딩 추상화: Converter와 Formatter - KwangtaekJung/inflearn-spring-framework-essential GitHub Wiki
- 데이터 바인딩 추상화: 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를 주입받아서 사용하면 된다.
하지만 이렇게 직접 주입받아서 사용하는 경우는 실제로는 거의 없을 것이다.
@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 로 직접 등록해줄 필요가 없음. 컨버터 빈은 컨버터로 포매터 빈은 포매터로 자동으로 등록해 준다.