Spring ConversionService

최준호·2022년 6월 1일
0

Spring

목록 보기
31/47
post-thumbnail

✍️ConversionService

ConversionService란 이전에 우리가 Convert Interface를 상속받아 구현했던 Converter들을 등록해서 사용할 수 있게 제공해주는 interface이다. 바로 사용해서 확인해보자.

public class ConversionServiceTest {

    @Test
    void conversionService(){
        DefaultConversionService conversionService = new DefaultConversionService();
        conversionService.addConverter(new StringToIntegerConverter());
        conversionService.addConverter(new IntegerToStringConverter());
        conversionService.addConverter(new StringToIpPortConverter());
        conversionService.addConverter(new IpPortToStringConverter());

        Assertions.assertEquals(conversionService.convert("10", Integer.class),10);
        Assertions.assertEquals(conversionService.convert(10, String.class),"10");

        IpPort ipPort = conversionService.convert("127.0.0.1:8080", IpPort.class);
        Assertions.assertEquals(ipPort,new IpPort("127.0.0.1", 8080));

        String ipPortString = conversionService.convert(new IpPort("127.0.0.1", 8080), String.class);
        Assertions.assertEquals(ipPortString, "127.0.0.1:8080");

    }
}

다음과 같이 테스트 코드를 작성하고 실행해보면

다음과 같이 자동으로 등록되어 사용할 때 Service가 자동으로 찾아서 변환한 뒤 반환해주는 작업이 진행되는 것을 알 수 있다.

ConversionService를 통해 ISP(Interface Segregation Principal) 인터페이스 분리 원칙을 지킬 수 있게 되는데. 우리는 메서드에 의존하지 않고 ConversionService.convert() 라는 메서드 하나로 모든 변환 메서드를 사용할 수 있기 때문이다.

스프링에는 SOLID가 잘 적용되어 있는 예제들을 많이 볼 수 있다. 해당 interface도 그 예제 중 하나이니 참고해두면 좋다!

🔨Spring에 Converter 적용하기

@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addFormatters(FormatterRegistry registry) {
        registry.addConverter(new StringToIntegerConverter());
        registry.addConverter(new IntegerToStringConverter());
        registry.addConverter(new IpPortToStringConverter());
        registry.addConverter(new StringToIpPortConverter());
    }
}

Spring에 우리가 만든 Converter들을 등록해주자. 위 코드와 같이 addFormatters() 메서드를 오버라이드 해주면 끝난다.

http://localhost:8080/hello-v2?data=2 url로 요청하게 되면 원래 잘 변환되어 나오긴 했던 코드지만 이전과 다른점은 우리가 등록했던 Converter가 더 우선순위를 가지며 해당 Converter가 동작했다는 것을 알수 있다.

우리가 만든 Class로 테스트해보자!

그럼 Spring에서 기본 제공해주지 않은 IpPort와 같은 Class로 테스트해보자.

@RestController
public class HelloController {

	...
    
    @GetMapping("/ip-port")
    public String helloV3(@RequestParam IpPort ipPort){
        System.out.println("ipPort.getIp() = " + ipPort.getIp());
        System.out.println("ipPort.getPort() = " + ipPort.getPort());
        return "ok";
    }
}

Controller를 추가하고

http://localhost:8080/ip-port?ipPort=127.0.0.1:8080 url로 요청해주면

잘 동작하는 것을 확인할 수 있다.

해당 과정은 @RqeustParam 뿐만 아니라 @RequestParam에서도 잘 동작한다. @RequestParam을 처리한ㄴ ArgumentResolver인 RequestParamMethodArgumentResolver에서 ConversionService를 사용하여 타입을 변환하는 내부 과정이 있는데. 더 깊이 확인하고 싶으면 IpPortConverter에 디버그를 찍어 보면 된다!

profile
코딩을 깔끔하게 하고 싶어하는 초보 개발자 (편하게 글을 쓰기위해 반말체를 사용하고 있습니다! 양해 부탁드려요!) 현재 KakaoVX 근무중입니다!

0개의 댓글