본문 바로가기

스프링

093.WEB_Converter

PropertyEditor는 매번 바인딩 할 때마다 새로운 오브젝트를 만들어야하는 약점이 있다. 제법 스프링을 잘 안다는 개발자들이 프로퍼티 에디터를 무책임하게 싱글톤 빈으로 사용하는 모습도 종종 발견된다. 그만큼 프로퍼티 에디터는 근본적인 위험성을 지니고 있고 불편하다.

> 그래스 스프링3.0에는 PropertyEditor를 대신할 수 있는 새로운 타입 변환 API Converter 인터페이스가 도입됐다.

* Converter

> PropertyEditor와는 다르게 변환 과정에서 메소드가 한번만 호출된다. 즉 변환 작업 중에 상태를 인스턴스 변수로 저장하지 않는다는 뜻이다.

> 멀티스레드 환경에서 안전하게 공유해서 쓸 수 있다. , 스프링의 싱글톤 빈 등록이 가능하다.

 

* Converter는 위처럼 소스와 타깃의 타입을 임의로 지정할 수 있다. PropertyEditor처럼 한쪽이 스트링 타입의 문자열로 고정되어 있지 않아 소스 타입과 타깃 타입을 미리 지정해둘 수 있다.

 

1.     Com.springsource.javax.activation : Spring java-mail

2.     Com.springsource.javax.inject-1.0.0 : 프로토타입 프로퍼티 에디터를 위한 jar. @Inject, Provider인터페이스<PropertyEditorSupport> 지원

3.     Com.springsource.javax.mail : Spring java-mail

4.     Com.springsource.javax.servlet.jsp.jstl : JstlView

5.     Com.springsource.org.aopalliance : Spring ProxyFactoryBean

6.     Com.springsource.org.aspectj.tools : AspectJExpressionPointcut 포인트컷 표현식 지원

7.     Com.springsource.org.cator.core : 자동으로 자바 오브젝트를 XML로 변환 지원.

8.     Com.springsource.org.cator.xml : 자동으로 자바 오브젝트를 XML로 변환 지원.

9.     Com.springsource.junit : junit

10.   Commons-logging : Spring-context가 사용

11.   Jackson-annotation : MappingJackson2JsonView

12.   Jackson-core : MappingJackson2JsonView

13.   Jackson-databind : MappingJackson2JsonView

14.   Mail : java-mail

15.   Mockito : 목 프레임워크 중 Mockito

16.   Mysql-connector : Mysql JDBC

17.   Org.springframework.context.support : Spring java-mail

18.   Org.springframework.oxm : Object-XML Mapping. 마샬러 빈을 지정해 모델에서 변환에 사용할 오브젝트를 지정해주면, OXM마샬러를 통해 모델 오브젝트를 XML로 변환해서 뷰의 결과로 사용할 수 있음.

19.   Spring-aop : 스프링 기능 자체의 aop, Spring ProxyFactoryBean

20.   Spring-bean : 스프링 코어와 함께 의존성 주입 제공 (Core Container)

21.   Spring-context : 스프링 코어, BeanFactory를 확장한 어플리케이션 컨텍스트 구현, 리소스 로드 및 국제화 지원(Core Container)

22.   Spring-core : 다른 스프링 모듈이 사용하는 유틸리티(Core Container)

23.   Spring-expression : EL 확장 Bean속성(배열, 컬렉션 포함).(Core Container)

24.   Spring-jdbc : 스프링이 지원하는 jdbc.

25.   Spring-test.jar

-       @RunWith : Junit 프레임워크의 테스트 실행방법을 확장시 사용.

-       SpringJUnit4ClassRunner : 어플리케이션컨텍스트를 만들고 관리하는 확장 클래스

-       @ContextConfiguration(경로) : 자동으로 만들어줄 어플리케이션 컨텍스트 설정파일

26.   Spring-tx : DuplicateKeyException.class 파일 존재 및 스프링 트랜잭션

27.   Spring-web : ContextLoaderListener 내장 루트 컨텍스트(서비스,DAO)

28.   Spring-webmvc : SpringMVC를 위한 리졸버, 모델앤뷰 등 지원

 

테스트 디스패처 서블릿을 위한 인터페이스

 

* 번거로운 XML 설정 대신 AbstractDispatcherServletTest를 사용

25. DispatcherServlet 초기화시 ServletConfig 오브젝트를 만들어 초기화해야함.

50. ContextRoot 값이 있을 때 추가해줌

54. setServletPath : 컨텍스트 root를 넣을 수 있도록 셋팅

58. requesturi 정보와 get,post mothod 셋팅 및 리스판스 객체 생성

 

81. 테스트 DispatcherServlet Init

 

 

 

 

46. LevelPropertyEditor처럼 Level 이늄 오브젝트를 스트링 타입으로 변환하는 컨버터(도메인 객체를 받을 때 사용됨. @ModelAttribute)

51. 반대로 스트링 타입 오브젝트를 Level 오브젝트로 변환하는 컨버터. (일반 스트링 파라미터 받을 때 위 예제는 다 이거씀)

* PropertyEditor처럼 Converter타입의 컨버터를 개별적으로 추가하는 대신 ConversionService 타입의 오브젝트를 통해 WebDataBinder에 설정해줘야 한다.

37. GenericConvertersionService : 컨버터를 만드는 것 뿐만 아닌 필드 컨텍스트를 제공 받을 수 있다. 필드 컨텍스트란 바인딩 작업시 제공받을 수 있는 메타정보(단순히 오브젝트 타입 뿐 아니라 클래스의 필드에 부여되어 있는 애노테이션, 제네릭스 타입 파라미터, 변환 대상인 메소드 파라미터 정보 등을 말함)

42. ConverterFactory : 제네릭스를 활용해서 특정 타입에 대한 컨버터 오브젝트를 만들어주는 팩토리 구현시 사용된다. 23라인에 팩토리 오브젝트를 주입해줘도 돌아감.

29. @InitBinder : 컨버터를 DI받아 메소드를 통해 WebDataBinder에 설정하는 방식으로 사용한다.

27. 위처럼 테스트 디스패처를 주입받을 수 있지만, 아래 XML방식으로 해도 주입받는다.

 

 

XML방식의 컨버터 빈 등록. 물론 GenericConversionService를 등록해도됨.

* 이렇게 해주면 ConversionServiceFactoryBean 빈을 통해 등록된 컨버터들이 모든 컨트롤러의 메소드 파라미터 바인딩에 사용될 것이다.

* 모든 컨트롤러에서 일일이 귀찮게 DI@InitBinder 메소드를 사용해서 일일이 컨버전 서비스를 지정해주는 대신 모든 컨트롤러에 한번에 적용하는 방법도 있다. 프로퍼티 에디터를 정의할 때 사용했던 WebBindingInitializer(091)를 이용하면 된다. WebBindingInitializer는 모든 컨트롤러에 일괄 적용되는 @InitBinder 메소드를 정의한 것이라고 볼 수 있다.

> 프로퍼티 에디터처럼 WebBindingInitializer를 구현한 클래스를 만들고 이를 빈으로 등록해도 되지만, ConversionService를 적용할 때는 ConfigurableWebBindingInitializer를 사용하면 편리하다. 코드를 따로 작성하지 않고 빈 설정만으로도 WebBindingInitializer 빈을 등록할 수 있기 때문이다.

 

설정이 좀 많아져서 복잡해 보이지만, 이렇게만 해두면 컨트롤러에서 직접 ConversionService 타입 빈을 DI받고 @InitBinder 메소드를 이용해 바인더를 초기화하는 코드를 모두 제거할 수 있기 때문에 전체적으로 컨트롤러 코드를 단순하게 만들 수 있다는 장점이 있다.