spring的监听器的几种使用方式

Java的spring事件监听模型还是很好用的。这里主要讲监听器的注解的使用方式。

最重要的有俩种注解

作用 适用场景
@EventListener 标记方法为事件监听器 通用事件监听,*(非事务)
@TransactionalEventListener 事务相关的事件监听 需要事务绑定的事件(事务)

对于@EventListener,有三个参数

value、classes、condition

value和classes主要是指定相关事件的

condition是最常用的,使用Spring Expression Language (SpEL) 实现动态过滤。.

SpEL 表达式可以访问以下变量:

变量名 等价形式 说明
#root.event event 当前事件对象
#root.args args 方法参数数组
#a0, #p0 args[0] 第一个参数
#a1, #p1 args[1] 第二个参数
#orderEvent 参数名为 orderEvent 的参数

也可以动态的注册一个spel函数

java 复制代码
 public static boolean calculateLength(int type, String article) {
            //通过枚举解析type
//解析长度
        }

讲其注入到context中去

java 复制代码
static class SpelFunctionRegister implements BeanFactoryAware, ApplicationContextAware {
        
        @Override
        public void setBeanFactory(BeanFactory beanFactory) 
               throws BeansException {
            // 注册自定义函数
            StandardEvaluationContext context = 
                ((StandardEvaluationContext) 
                 beanFactory.getBean(StandardEvaluationContext.class));
            
            try {
                // 注册一个计算评论内容的函数
                context.registerFunction("calculateLength",
                    CustomSpELFunctions.class.getDeclaredMethod(
                        "calculateLength", 
                        Integer.class, String.class));
            } catch (NoSuchMethodException e) {
                throw new RuntimeException("注册SpEL函数失败", e);
            }
        }
     
    }
java 复制代码
@EventListener(condition = 
        "#calculatLenth(#event.commentType, #event.article)")
    public void handleDiscountOrder(OrderEvent event) {
        //符合评论类型、评论内容
    }

实际项目更常用的还是@TransactionalEventListener

将事件监听与数据库事务的生命周期绑定,解决了"何时触发事件处理"这个关键问题。

退可当普通监听器使用,进可处理事务相关的监听,

定义了四个参数

1:phase(重要参数) :以下四个策略

java 复制代码
public enum TransactionPhase {
    // 四个关键阶段
    BEFORE_COMMIT,    // 事务提交前
    AFTER_COMMIT,     // 事务提交后(默认)是最常用的
    AFTER_ROLLBACK,   // 事务回滚后  
    AFTER_COMPLETION  // 事务完成后(无论成功失败)
}

2**:value() 就是指定监听具体的事件的,含义差不多
3: classes() 就是指定监听具体的事件的,含义差不多**

4:condition() 与@EventListenner差不多一个东西

为什么说@EventListener在实际项目好像使用的更多一点,平时写代码不怎么使用这玩意呢

1:大部分表的update、delete、add肯定都会用事务进行包装,而对于这些增删改操作又会涉及到一系列的问题。比如清理缓存、一致性补偿、异步编排等等十分常见,将代码解耦合。对于实际项目的一个接口而言代码过长不利于扩展、理解以及数据的正确性

2:清理多节点本地缓存也十分常用,对于多节点的分布式系统而言,不可能都采用的远程缓存来做,必然有很多的本地缓存,或者是本地+远程远程来做的,如果涉及到缓存数据相关业务数据的变更,如果我只在当前节点进行清理缓存,那么其他节点就有可能有脏数据的问题,如果缓存时间还长,那线上环境的影响是很大的。比如清理所有节点的更新的业务缓存数据。对于采用了本地缓存的业务,在业务变更需要进行publis事件来清除缓存是最高效的。

相关推荐
橘子131 分钟前
MySQL连接(十四)
数据库·mysql
奋斗的小方3 分钟前
01 一文读懂UML类图:核心概念与关系详解
java·uml
m0_706653233 分钟前
用Python创建一个Discord聊天机器人
jvm·数据库·python
长安城没有风7 分钟前
Java 高并发核心编程 ----- 线程池原理与实践(上)
java·juc
Remember_9937 分钟前
Spring 核心原理深度解析:Bean 作用域、生命周期与 Spring Boot 自动配置
java·前端·spring boot·后端·spring·面试
渡我白衣12 分钟前
【MySQL基础】(2):数据库基础概念
数据库·人工智能·深度学习·神经网络·mysql·机器学习·自然语言处理
风流倜傥唐伯虎13 分钟前
java多线程打印
java·多线程
80530单词突击赢16 分钟前
云原生时代:.NET与Java的K8s进化论
java
hhy_smile18 分钟前
Special method in class
java·开发语言
alien爱吃蛋挞19 分钟前
【JavaEE】万字详解Mybatis(上)
数据库·java-ee·mybatis