事件发布
定义事件
public class TestEvent extends ApplicationEvent { public TestEvent(Object source) { super(source); } }
定义事件监听器
public class TestListener implements ApplicationListener<TestEvent> { @Override public void onApplicationEvent(TestEvent event) { System.out.println("收到一个事件 ,,,,,"); } }
调用程序
@Configuration public class ApplicationEventTest { @Bean public ApplicationListener applicationListener() { return new TestListener(); } public static void main(String[] args) { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ApplicationEventTest.class); context.publishEvent(new TestEvent(new Object())); } }
类型转换
Spring 内部,有很多地方可能需要将 String 转换为其他类型,今天我们一起来学习一下 PropertyEditor、 ConversionService、TypeConverter 三种类型转换的使用。
PropertyEditor
PropertyEditor 是 JDK 提供的类型转换器,首先创建 bean :
@Service public class OrderService { @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({OrderService.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) { // 使用方式 1 String2ObjectPropertyEditor propertyEditor = new String2ObjectPropertyEditor(); propertyEditor.setAsText("1"); Object value = propertyEditor.getValue(); System.out.println(value); // 使用方式 2 ApplicationContext applicationContext = new AnnotationConfigApplicationContext(PropertyEditorTest.class); OrderService orderItemService = applicationContext.getBean(OrderService.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); } }
单独使用
DefaultConversionService conversionService = new DefaultConversionService(); conversionService.addConverter(new String2ObjectConversionService()); Order order = conversionService.convert("1", Order.class); System.out.println(order);
在 Spring 中使用:
@Bean public ConversionServiceFactoryBean conversionService() { ConversionServiceFactoryBean conversionServiceFactoryBean = new ConversionServiceFactoryBean(); conversionServiceFactoryBean.setConverters(Collections.singleton(new String2ObjectConversionService())); return conversionServiceFactoryBean; }
Bean 的注入和调用代码:
// 测试和注入 @Service public class OrderService { //通过 @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; }
OrderComparator
OrderComparator 是 Spring 提供的一种比较器,可以根据 @Order 注解或者实现 Ordered 接口来进行比较,从而进行排序。比如:
public class A implements Ordered { @Override public int getOrder() { return 1; } }
public class B implements Ordered { @Override public int getOrder() { return 2; } }
排序使用:
public class OrderComparatorTest { public static void main(String[] args) { A a = new A(); B b = new B(); OrderComparator orderComparator = new OrderComparator(); System.out.println(orderComparator.compare(a, b)); // -1 List list = new ArrayList(); list.add(a); list.add(b); list.sort(orderComparator); System.out.println(list); // a,b } }