1. Spring Type Conversion
- 타입 변환 시스템 (기존 PropertyEditor의 대안)
기능
- 외부 문자열을 자바 타입으로 변화
- 애플리케이션 전반에서 타입 변환 API로 활용함
주요 인터페이스
| 인터페이스 | 설명 | 
| Converter<S, T> | 가장 기본적인 변환기. S → T로 단일 타입 변환 | 
| ConverterFactory<S, R> | 변환 대상이 계층 구조일 때 사용 (ex. String → Enum) | 
| GenericConverter | 다중 타입 지원. 유연하지만 복잡 | 
| ConditionalGenericConverter | 특정 조건에 따라 변환 수행 (어노테이션, 메소드 존재 등) | 
| ConversionService | 런타임에서 변환 실행하는 중앙 API | 
| ConverterRegistry | 변환기 등록용 SPI | 
예제) Converter
더보기
public class StringToIntegerConverter implements Converter<String, Integer> {
    @Override
    public Integer convert(String source) {
        return Integer.valueOf(source);
    }
}
예제) ConverterFactory
더보기
public class StringToEnumConverterFactory implements ConverterFactory<String, Enum> {
    @Override
    public <T extends Enum> Converter<String, T> getConverter(Class<T> targetType) {
        return new StringToEnumConverter<>(targetType);
    }
    private static class StringToEnumConverter<T extends Enum> implements Converter<String, T> {
        private final Class<T> enumType;
        public StringToEnumConverter(Class<T> enumType) {
            this.enumType = enumType;
        }
        @Override
        public T convert(String source) {
            return (T) Enum.valueOf(this.enumType, source.trim().toUpperCase());
        }
    }
}- String -> Enum
예제) GenericConverter
더보기
public class StringArrayToIntegerListConverter implements GenericConverter {
    @Override
    public Set<ConvertiblePair> getConvertibleTypes() {
        return Set.of(new ConvertiblePair(String[].class, List.class));
    }
    @Override
    public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
        String[] array = (String[]) source;
        List<Integer> list = new ArrayList<>();
        for (String s : array) {
            list.add(Integer.valueOf(s));
        }
        return list;
    }
}- String[] -> List<Integer>
예제) ConditionalGenericConverter
더보기
public class IdToEntityConverter implements ConditionalGenericConverter {
    @Override
    public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) {
        try {
            targetType.getType().getMethod("findById", Long.class);
            return true;
        } catch (NoSuchMethodException e) {
            return false;
        }
    }
    @Override
    public Set<ConvertiblePair> getConvertibleTypes() {
        return Set.of(new ConvertiblePair(Long.class, Object.class));
    }
    @Override
    public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
        Long id = (Long) source;
        try {
            Method method = targetType.getType().getMethod("findById", Long.class);
            return method.invoke(null, id);
        } catch (Exception e) {
            throw new IllegalArgumentException("변환 실패", e);
        }
    }
}- Long -> Entity
예제) ConversionService
더보기
public class MyService {
    private final ConversionService conversionService;
    public MyService(ConversionService conversionService) {
        this.conversionService = conversionService;
    }
    public void convertList() {
        List<Integer> integers = List.of(1, 2, 3);
        TypeDescriptor sourceType = TypeDescriptor.forObject(integers);
        TypeDescriptor targetType = TypeDescriptor.collection(List.class, TypeDescriptor.valueOf(String.class));
        List<String> result = (List<String>) conversionService.convert(integers, sourceType, targetType);
        System.out.println(result); // ["1", "2", "3"]
    }
}- List<Integer> -> List<String>
예제) ConverterRegistry
더보기
// ConversionService + ConverterRegistry 기능을 함께 제공하는 클래스
DefaultConversionService conversionService = new DefaultConversionService();
// ConverterRegistry 기능 사용: 커스텀 컨버터 등록
conversionService.addConverter(new StringToIntegerConverter());
conversionService.addConverterFactory(new StringToEnumConverterFactory());
// ConversionService 기능 사용: 타입 변환
Integer number = conversionService.convert("123", Integer.class);
System.out.println(number); // 123
// Enum 변환 예제
MyEnum myEnum = conversionService.convert("FIRST", MyEnum.class);
System.out.println(myEnum); // FIRSTDefaultConversionService cs = new DefaultConversionService();
List<Integer> input = ...
cs.convert(input,
	TypeDescriptor.forObject(input), // List<Integer> type descriptor
	TypeDescriptor.collection(List.class, TypeDescriptor.valueOf(String.class)));
기본 구현체
| 인터페이스 종류 | 구현체 이름 | 설명 | 
| Converter<S, T> | StringToIntegerConverter | 문자열 → 정수 변환 | 
| StringToBooleanConverter | 문자열 → 불리언 변환 | |
| IntegerToStringConverter | 정수 → 문자열 변환 | |
| BooleanToStringConverter | 불리언 → 문자열 변환 | |
| NumberToNumberConverter | 숫자 타입끼리 변환 (Integer → Long, Double 등) | |
| ConverterFactory<S, R> | StringToEnumConverterFactory | 문자열 → Enum 변환 | 
| NumberToNumberConverterFactory | 숫자 간 다양한 변환 지원 | |
| GenericConverter | ObjectToStringConverter | toString() 기반 변환 | 
| IdToEntityConverter | (예: ID → JPA Entity, 직접 구현 필요) | 
등록
- Converter 관련 구현체를 빈으로 등록하면, 자동으로 ConverterRegistry에 등록됨
- 내부적으로 FormattingConversionServiceFactoryBean이 모든 Converter / GenericConverter를 수집함
출처
'Spring > Spring' 카테고리의 다른 글
| [Spring][Object] 1. Data Binding (0) | 2025.04.06 | 
|---|---|
| [Spring][Field] 2. Formatting (0) | 2025.04.06 | 
| [Spring][Core] 3-5. Container: Additional Capabilities of the ApplicationContext (0) | 2025.04.06 | 
| [Spring][Core] 3-4. Container: Environment Abstraction (0) | 2025.04.06 | 
| [Spring][Core] 3-3. Container: Using JSR 330 Standard Annotations (0) | 2025.04.06 |