데이터바이딩이란 어떤 프로퍼티의 값을 타겟객체에 설정하는 것을 뜻한다. Spring 사용자 관점에서 보면 사용자가 입력한 값을 애플리케이션 도메인 객체에 동적으로 할당하는 기능다. Spring에서는 사용자가 입력한 값은 문자열이고도메인 객체에 맞는 자료형으로 변경 필요하기 때문에 추상화 되었다.
데이터 바인딩 추상화(PropertyEditor) 구현체
org.springframework.validation.DataBinder
java.beans.PropertyEditor
PropertyEditor 사용 1 2 3 4 5 6 7 8 9 10 11 12 13 public class EventEditor extends PropertyEditorSupport { @Override public String getAsText () { Event event = (Event)getValue(); return event.id.toString(); } @Override public void setAsText (String text) throws IllegalArgumentException { setValue(new Event(Integer.parseInt(text))); } }
스프링 3.0 이전까지 DataBinder가 변환 작업 사용하던 인터페이스
쓰레드-세이프 하지 않음 -> controller 단에 등록하여 사용
1 2 3 4 5 6 7 8 9 10 11 12 13 14 @RestController public class EventController { @InitBinder public void init (WebDataBinder webDataBinder) { webDataBinder.registerCustomEditor(Event.class , new EventEditor ()) ; } @GetMapping ("/event/{event}" ) public String getEvent (@PathVariable Event event) { System.out.println(event); return event.getId().toString(); } }
Object와 String 간의 변환만 할 수 있어, 사용 범위가 제한적 임.
Converter
S 타입을 T 타입으로 변환할 수 있는 매우 일반적인 변환기.
상태 정보 없음 (Stateless == 쓰레드세이프)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 public class EventConverter { public static class StringToEventConverter implements Converter <String , Event > { @Override public Event convert (String source) { return new Event(Integer.parseInt(source)); } } public static class EventToStringConverter implements Converter <Event , String > { @Override public String convert (Event source) { return source.getId().toString(); } } }
ConverterRegistry 에 등록해서 사용
1 2 3 4 5 6 7 @Configuration public class WebConfig implements WebMvcConfigurer { @Override public void addFormatters (FormatterRegistry registry) { registry.addConverter(new EventConverter.StringToEventConverter()); } }
PropertyEditor 대체제
Object와 String 간의 변환을 담당
문자열을 Locale에 따라 다국화하는 기능도 제공
1 2 3 4 5 6 7 8 9 10 11 public class EventFormatter implements Formatter <Event > { @Override public Event parse (String text, Locale locale) throws ParseException { return new Event(Integer.parseInt(text)); } @Override public String print (Event object, Locale locale) { return object.getId().toString(); } }
FormatterRegistry 에 등록해서 사용
1 2 3 4 5 6 7 @Configuration public class WebConfig implements WebMvcConfigurer { @Override public void addFormatters (FormatterRegistry registry) { registry.addFormatter(new EventFormatter()); } }
1 2 3 4 5 6 7 8 9 public class EventConverter { @Component public static class StringToEventConverter implements Converter <String , Event > { @Override public Event convert (String source) { return new Event(Integer.parseInt(source)); } } }
1 2 3 4 5 6 7 8 @Component public class EventFormatter implements Formatter <Event > { @Override public Event parse (String text, Locale locale) throws ParseException { return new Event(Integer.parseInt(text)); } }
ConversionService
실제 변환 작업은 이 인터페이스를 통해서 쓰레드-세이프하게 사용 가능
스프링 MVC , 빈 (value) 설정, SpEL에서 사용
DefaultFormattingConversionService
FormatterRegistry
ConversionService
여러 기본 컨버터, 포매터 자동 등록
스프링 부트
웹 애플리케이션인 경우에 DefaultFormattingConversionSerivce를 상속하여 만든 WebConversionService 를 빈으로 등록
Formatter와 Converter 빈을 찾아 자동 등록
등록된 ConversionService들 조회
1 2 3 4 5 6 7 8 9 10 11 @Component public class AppRunner implements ApplicationRunner { @Autowired ConversionService conversionService; @Override public void run (ApplicationArguments args) throws Exception { System.out.println(conversionService); } }
1 2 3 4 5 ConversionService converters = @org.springframework.format.annotation.DateTimeFormat java.lang.Long -> java.lang.String: org.springframework.format.datetime.DateTimeFormatAnnotationFormatterFactory@3b95a6db,@org.springframework.format.annotation.NumberFormat java.lang.Long -> java.lang.String: org.springframework.format.number.NumberFormatAnnotationFormatterFactory@309cedb6 @org.springframework.format.annotation.DateTimeFormat java.time.LocalDate -> java.lang.String: org.springframework.format.datetime.standard.Jsr310DateTimeFormatAnnotationFormatterFactory@36b9cb99,java.time.LocalDate -> java.lang.String : org.springframework.format.datetime.standard.TemporalAccessorPrinter@4130955c @org.springframework.format.annotation.DateTimeFormat java.time.LocalDateTime -> .....
Contributors