PropertyEditor
PropertyEditor 是 JDK 提供的类型转换器,首先创建 bean :
@Service public class OrderItemService { @Value("orderVal") private Order order; public void test() { System.out.println("test order : " + order); } }
创建类型转换器,将字符串转换为 Order 实例对象。
public class String2ObjectPropertyEditor extends PropertyEditorSupport implements PropertyEditor { @Override public void setAsText(String text) throws IllegalArgumentException { Order order = new Order(); order.setName("haha"); order.setAge(12); this.setValue(order); } }
注册转换器以及测试代码:
@Import({OrderItemService.class}) @Configuration public class PropertyEditorTest { @Bean public CustomEditorConfigurer customEditorConfigurer() { Map<Class<?>, Class<? extends PropertyEditor>> customEditors = new HashMap<>(); customEditors.put(Order.class, String2ObjectPropertyEditor.class); CustomEditorConfigurer customEditorConfigurer = new CustomEditorConfigurer(); customEditorConfigurer.setCustomEditors(customEditors); return customEditorConfigurer; } public static void main(String[] args) { ApplicationContext applicationContext = new AnnotationConfigApplicationContext(PropertyEditorTest.class); OrderItemService orderItemService = applicationContext.getBean(OrderItemService.class); orderItemService.test(); } }
ConversionService
ConversionService 是 Sprign 中提供的类型转换器,它比 PrppertyEditor 功能更加强大。 定义转换器:
public class String2ObjectConversionService implements ConditionalGenericConverter { @Override public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) { return Objects.equals(sourceType.getType(), String.class) && Objects.equals(targetType.getType(), Order.class); } @Override public Set<ConvertiblePair> getConvertibleTypes() { return Collections.singleton(new ConvertiblePair(String.class, Order.class)); } @Override public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { return new Order("haha", 32); } }
在 Spring 中使用:
@Bean public ConversionServiceFactoryBean conversionService() { ConversionServiceFactoryBean conversionServiceFactoryBean = new ConversionServiceFactoryBean(); conversionServiceFactoryBean.setConverters(Collections.singleton(new String2ObjectConversionService())); return conversionServiceFactoryBean; }
Bean 的注入和调用代码:
// 测试和注入 @Service public class OrderItemService { //通过 @Value 注入 @Value("orderVal") private Order order; public void test() { System.out.println("test order : " + order); } } // 调用代码 ApplicationContext appliciton = new AnnotationConfigApplicationContext(ConvertTest.class); OrderItemService orderItemService = appliciton.getBean(OrderItemService.class); orderItemService.test();
TypeConverter
TypeConverter 整合了 PropertyEditor 和 ConversionService, 在 Spring 内部使用:
SimpleTypeConverter typeConverter = new SimpleTypeConverter(); typeConverter.registerCustomEditor(Order.class, new String2ObjectPropertyEditor()); Order order = typeConverter.convertIfNecessary("orderVal", Order.class); System.out.println(order);
比如在 AbstractBeanFacotry#adaptBeanInstance
中也有用到:
// AbstractBeanFacotry.java <T> T adaptBeanInstance(String name, Object bean, @Nullable Class<?> requiredType) { // Check if required type matches the type of the actual bean instance. // 如果转换类型不为空,并且 bean 类型与目标类型不匹配 if (requiredType != null && !requiredType.isInstance(bean)) { try { // 尝试转换 Object convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType); if (convertedBean == null) { throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass()); } return (T) convertedBean; } catch (TypeMismatchException ex) { if (logger.isTraceEnabled()) { logger.trace("Failed to convert bean '" + name + "' to required type '" + ClassUtils.getQualifiedName(requiredType) + "'", ex); } throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass()); } } return (T) bean; }