『深入学习 Spring Boot』(五) 从Spring Boot 中的监听器模式学到了什么?

370 阅读2分钟

前言

之前翻阅了 Spring Boot 源码中的监听器模式,多多少少得有点收获吧。

读 Spring Boot 对监听器模式实践所得

巩固监听器模式相关知识

作为探究 Spring Boot 监听器部分源码的前置知识,在 《『深入学习 Spring Boot』(三) Spring Boot 中的监听器模式 (上) 》中,首先实现了一个简单的监听器模式,作为我们继续探究的基石。

了解了监听器的扩展用法

例如,可以使用一个类来对广播器发送事件来进行包装,从而把事件类不对外暴露。

我们就延续之前写的简单 demo 改造:

// 广播器包装类
@Component
public class DailyLifeRunListener {
    @Autowired
    private DailyLifeEventMulticaster eventMulticaster;
    public void snow() {
        eventMulticaster.multicastEvent(new FangPiEvent());
    }
    public void rain() {
        eventMulticaster.multicastEvent(new LaShiEvent());
    }
}

监听器所监听事件可以用泛型来标识

当某监听器只需要监听一个事件时,可用考虑用泛型来表示所监听的事件。

  1. 改造监听器

    public interface DailyLiferListener<T extends DailyLlifeEvent> {
        void onDailyLlifeEvent(DailyLlifeEvent event);
    }
    
  2. 改造拉屎事件

    @Component
    public class LaShiListener implements DailyLiferListener<LaShiEvent> {
        @Override
        public void onDailyLlifeEvent(DailyLlifeEvent event) {
            ResolvableType generic = ResolvableType.forClass(this.getClass()).as(DailyLiferListener.class).getGeneric();
            if (generic.isAssignableFrom(LaShiEvent.class)) {
                System.out.println("化粪池注意:你"+event.getBehavior()+"了");
            }else {
                System.out.println("不感兴趣的事件已略过");
            }
        }
    }
    

ResolvableType

这是一个与监听器无关的类。但是在 Spring Boot 监听器模式中被广泛地使用。

ResolvableType 是 Spring 为简化对泛型信息的提取封装的工具类。

public class ResolvableType implements Serializable {
 
    // 根据原始类型 Class 创建 ResolvableType
    public static ResolvableType forClass(@Nullable Class<?> clazz);
 
    // 根据构造器参数创建 ResolvableType
    public static ResolvableType forConstructorParameter(Constructor<?> constructor, int parameterIndex);
 
    // 根据成员变量创建 ResolvableType
    public static ResolvableType forField(Field field);
 
    // 根据实例创建 ResolvableType
    public static ResolvableType forInstance(Object instance);
 
    // 根据方法参数创建 ResolvableType
    public static ResolvableType forMethodParameter(Method method, int parameterIndex);
 
    // 根据方法的返回值创建 ResolvableType
    public static ResolvableType forMethodReturnType(Method method);
 
    // 根据原始类型信息创建 ResolvableType
    public static ResolvableType forRawClass(@Nullable Class<?> clazz);
 
    // 根据某一种类型创建 ResolvableType
    public static ResolvableType forType(@Nullable Type type);
}

以上是构造 ResolvableType 的静态方法。

下面我们用一组,获取泛型的泛型的泛型的方法,来了解 ResolvalbeType 使用的简单性:

public class RelolvableTypeExample {
    private Map<String, Map<Long, List<Integer>>> param;
 
    public static void main(String[] args) throws NoSuchFieldException {
        ResolvableType resolvableType = ResolvableType.forField(RelolvableTypeExample.class.getDeclaredField("param"));
        // 获取 Map<String, Map<Long, List<Integer>>> 中的 泛型String
        ResolvableType generic = resolvableType.getGeneric(0);
        System.out.println(generic.resolve()); // class java.lang.String
        // 获取 Map<String, Map<Long, List<Integer>>> 中的 泛型Map<Long, List<Integer>>
        ResolvableType generic1 = resolvableType.getGeneric(1); // interface java.util.Map
        System.out.println(generic1.resolve());
        // 获取泛型 Map<Long, List<Integer>> 的 泛型Long
        ResolvableType generic2 = generic1.getGeneric(0);// class java.lang.Long
        System.out.println(generic2.resolve());
        // 获取泛型 Map<Long, List<Integer>> 的 泛型List<Integer>
        ResolvableType generic3 = generic1.getGeneric(1);// interface java.util.List
        System.out.println(generic3.resolve());
        // 获取 泛型 List<Integer> 的泛型 Integer
        ResolvableType generic4 = generic3.getGeneric(0);// class java.lang.Integer
        System.out.println(generic4.resolve());
    }
}