Spring 核心概念与使用技巧(中)

简介: Spring 核心概念与使用技巧

事件发布


定义事件


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
  }
}


相关文章
|
7月前
|
Java Maven 数据安全/隐私保护
详解 Java AOP:面向方面编程的核心概念与 Spring 实现
详解 Java AOP:面向方面编程的核心概念与 Spring 实现
98 1
|
8月前
|
Java 关系型数据库 数据库
Spring Boot多数据源及事务管理:概念与实战
【4月更文挑战第29天】在复杂的企业级应用中,经常需要访问和管理多个数据源。Spring Boot通过灵活的配置和强大的框架支持,可以轻松实现多数据源的整合及事务管理。本篇博客将探讨如何在Spring Boot中配置多数据源,并详细介绍事务管理的策略和实践。
569 3
|
8月前
|
安全 Java 测试技术
Spring Boot集成支付宝支付:概念与实战
【4月更文挑战第29天】在电子商务和在线业务应用中,集成有效且安全的支付解决方案是至关重要的。支付宝作为中国领先的支付服务提供商,其支付功能的集成可以显著提升用户体验。本篇博客将详细介绍如何在Spring Boot应用中集成支付宝支付功能,并提供一个实战示例。
405 2
|
5月前
|
XML Java 数据库
Spring5入门到实战------15、事务操作---概念--场景---声明式事务管理---事务参数--注解方式---xml方式
这篇文章是Spring5框架的实战教程,详细介绍了事务的概念、ACID特性、事务操作的场景,并通过实际的银行转账示例,演示了Spring框架中声明式事务管理的实现,包括使用注解和XML配置两种方式,以及如何配置事务参数来控制事务的行为。
Spring5入门到实战------15、事务操作---概念--场景---声明式事务管理---事务参数--注解方式---xml方式
|
7月前
|
Java 数据库连接 Spring
Spring底层架构核心概念总结
Spring底层架构核心概念总结
|
7月前
|
消息中间件 Java Maven
深入理解Spring Boot Starter:概念、特点、场景、原理及自定义starter
深入理解Spring Boot Starter:概念、特点、场景、原理及自定义starter
|
7月前
|
前端开发 安全 Java
Spring EL表达式:概念、特性与应用深入解析
Spring EL表达式:概念、特性与应用深入解析
|
7月前
|
XML 负载均衡 Java
Spring Boot 中实现负载均衡:概念、功能与实现
【6月更文挑战第28天】在分布式系统中,负载均衡(Load Balancing)是指将工作负载和流量分配到多个服务器或服务实例上,以提高系统可用性和响应速度。负载均衡器可以是硬件设备,也可以是软件解决方案。
315 0
|
7月前
|
XML Java 数据库
Spring5系列学习文章分享---第五篇(事务概念+特性+案例+注解声明式事务管理+参数详解 )
Spring5系列学习文章分享---第五篇(事务概念+特性+案例+注解声明式事务管理+参数详解 )
38 0
|
7月前
|
SQL Java 数据库连接
Spring5系列学习文章分享---第四篇(JdbcTemplate+概念配置+增删改查数据+批量操作 )
Spring5系列学习文章分享---第四篇(JdbcTemplate+概念配置+增删改查数据+批量操作 )
43 0