在spting中,会遇到很多将String类型转换为其他类型的场景。Spring源码中提供了一些技术来更方便的做对象的类型转化。
在JDK中,给我们提供了PropertyEditor用来将String转换为指定类型。
User :
import lombok.Data;
@Data
public class User {
public User() {
System.out.println("无参构造");
}
private String name;
}
StringToUserPropertyEditor :
import java.beans.PropertyEditor;
import java.beans.PropertyEditorSupport;
public class StringToUserPropertyEditor extends PropertyEditorSupport implements PropertyEditor {
@Override
public void setAsText(String text) throws IllegalArgumentException {
User user = new User();
user.setName(text);
this.setValue(user);
}
}
Main:
public static void main(String[] args) {
StringToUserPropertyEditor propertyEditor = new StringToUserPropertyEditor();
propertyEditor.setAsText("1");
User value = (User) propertyEditor.getValue();
System.out.println(value);
}
import org.springframework.beans.factory.config.CustomEditorConfigurer;
import org.springframework.context.annotation.Bean;
import top.mingempty.spring.service.StringToUserPropertyEditor;
import top.mingempty.spring.service.User;
import java.beans.PropertyEditor;
import java.util.HashMap;
import java.util.Map;
public class AppConfig {
@Bean
public CustomEditorConfigurer customEditorConfigurer() {
CustomEditorConfigurer customEditorConfigurer = new CustomEditorConfigurer();
Map<Class<?>, Class<? extends PropertyEditor>> propertyEditorMap = new HashMap<>();
// 表示StringToUserPropertyEditor可以将String转化成User类型,在Spring源码中,如果发现当前对象是String,而需要的类型是User,就会使用该PropertyEditor来做类型转化
propertyEditorMap.put(User.class, StringToUserPropertyEditor.class);
customEditorConfigurer.setCustomEditors(propertyEditorMap);
return customEditorConfigurer;
}
}
UserService:
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
public class UserService {
@Value("demo")
private User user;
public void test() {
System.out.println("demo");
System.out.println(user);
}
}
Main:
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(context);
scanner.scan("com.ming.spring");
context.getBean("userService", UserService.class).test();
}
在spring中,也给我们提供了一个类型转化服务,它比PropertyEditor更强大。
StringToUserConverter :
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.core.convert.converter.ConditionalGenericConverter;
import java.util.Collections;
import java.util.Set;
public class StringToUserConverter implements ConditionalGenericConverter {
/**
* 判断是否要使用该类型转换器
*
* @param sourceType 原始类型
* @param targetType 目标类型
* @return
*/
@Override
public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) {
return sourceType.getType().equals(String.class) && targetType.getType().equals(User.class);
}
/**
* 此转换器可以转换的目标类型和原始类型的集合
*
* @return
*/
@Override
public Set<ConvertiblePair> getConvertibleTypes() {
return Collections.singleton(new ConvertiblePair(String.class, User.class));
}
/**
* 转换方法
*
* @param source 要被转换的数据
* @param sourceType 原始类型
* @param targetType 目标类型
* @return
*/
@Override
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
User user = new User();
user.setName((String) source);
return user;
}
}
Main:
public static void main(String[] args) {
DefaultConversionService conversionService = new DefaultConversionService();
conversionService.addConverter(new StringToUserConverter());
User value = conversionService.convert("1", User.class);
System.out.println(value);
}
import org.springframework.context.annotation.Bean;
import org.springframework.context.support.ConversionServiceFactoryBean;
import top.mingempty.spring.service.StringToUserConverter;
import java.util.Collections;
public class AppConfig {
@Bean
public ConversionServiceFactoryBean conversionService() {
ConversionServiceFactoryBean conversionServiceFactoryBean = new ConversionServiceFactoryBean();
conversionServiceFactoryBean.setConverters(Collections.singleton(new StringToUserConverter()));
return conversionServiceFactoryBean;
}
}
UserService:
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
public class UserService {
@Value("demo")
private User user;
public void test() {
System.out.println("demo");
System.out.println(user);
}
}
Main:
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(context);
scanner.scan("com.ming.spring");
context.getBean("userService", UserService.class).test();
}
整合了PropertyEditor和ConversionService的功能,是Spring内部用的。
public static void main(String[] args) {
SimpleTypeConverter typeConverter = new SimpleTypeConverter();
typeConverter.registerCustomEditor(User.class, new StringToUserPropertyEditor());
DefaultConversionService conversionService = new DefaultConversionService();
conversionService.addConverter(new StringToUserConverter());
typeConverter.setConversionService(conversionService);
User value = typeConverter.convertIfNecessary("1000", User.class);
System.out.println(value);
}