微信事件接收回调处理代码优化 反射 责任链模式 策略模式
最近在公司参与企微相关项目等开发,接触到了企微相关事件回调,由于企微回调事件较多,我们最初在程序里写了较多if,else去处理,客户是不认可这种低级方式的,我们开发人员也应该去避免这种代码的产生,所以我这里采用了几种方式去处理事件回调,大家也可以看看哪种处理方式是比较好的。
第一种 通过类反射的去得到相应的处理事件类
首先定义事件类的枚举
通过枚举去获取类名,再通过class.forname去获取类信息,并创建实例
优点: 代码简单易懂,后续扩展事件类只需要添加枚举
缺点: 事件类名称固定,如果修改,则导致事件无法接收,***技术经理说实在没办法才用这种
第二种 责任链模式
首先 定义一个接口,定义下一个接口类及处理事件的方法
定义事件接收类去继承改接口
配置责任链调用顺序
优点: 事件类可随意扩展
缺点:主流程代码过于臃肿,看着还不如if,else
第三种 策略模式
首先定义一个工厂,去获取所有处理事件类及匹配对应处理事件类的方法
定义一个接口,让处理事件类去继承
定义枚举类
定义事件类,@PostConstruct初始化注入到工厂的map中
主流程处理代码
优点 :主流程代码简单,且代码易扩展
缺点:感觉那个枚举类中定义事件类名还是有点呆
第四种 Spring-责任链模式
这是后来新想到的处理方式 Spring的出现可以使用责任链模式的代码优化得异常简单,下面看看具体代码上的实现
定义第三种一样的枚举,去找到对应的事件处理类
定义顶级接口
定义实现类,使用@Order注解,去实现Bean的加载顺序,类似于责任链的下一层调用
结合Spring官网提供的文档以及源码可以发现,在Spring中提供了如下的方法来进行Bean加载顺序的控制:
实现Ordered/PriorityOrdered接口;
使用@Order/@Priority注解,@Order注解可以用于方法级别,而@Priority注解则不行;
针对自定义的Bean而言,上述的方式都可以实现Bean加载顺序的控制。无论是实现接口的方式还是使用注解的方式,值设置的越小则优先级越高,而通过实现PriorityOrdered接口或者使用@Priority注解的Bean时其加载优先级会高于实现Ordered接口或者使用@Order注解的Bean。需要注意的是,使用上述方式只会改变实现同一接口Bean加载到集合(比如List、Set等)中的顺序(或者说优先级),但是这种方式并不会影响到Spring应用上下文启动时不同Bean的初始化顺序
使用(最好使用@Autowired,@Resource,Spring识别不了)@Autowired注解,将事件处理类注入到List中,事件类通过遍历List,去执行处理事件类的逻辑
// DefaultListableBeanFactory#resolveMultipleBeans部分代码
else if (type.isArray()) {
......
if (result instanceof Object[]) {
// 获取到比较器
Comparator<Object> comparator = adaptDependencyComparator(matchingBeans);
if (comparator != null) {
Arrays.sort((Object[]) result, comparator);
}
}
return result;
}
else if (Collection.class.isAssignableFrom(type) && type.isInterface()) {
......
if (result instanceof List) {
if (((List<?>) result).size() > 1) {
// 获取到比较器
Comparator<Object> comparator = adaptDependencyComparator(matchingBeans);
if (comparator != null) {
((List<?>) result).sort(comparator);
}
}
}
return result;
}
从上面的代码中可以看到,可以进行顺序控制的Bean类型只有数组类型Object[]和List类型,其他类型的成员Bean是无法进行加载顺序控制的。
主流程调用 在主类中注入工厂调用方法。
这就是处理微信事件回调代码优化我的几个解决方案,如果有更好的方式,可以评论一下。