ApplicationListener详解

一、ApplicationListener的原理

ApplicationListener(应用程序监听器)是Spring Framework中的一个事件机制,Spring在运行时触发各类事件,如web应用程序上下文的启动完成事件、servlet请求及响应事件、消息事件等。这些事件可以被应用程序监听器感知到并处理,可以进行自定义的扩展和操作。

二、ApplicationListener的增加和删除

增加ApplicationListener较为简单,只需要实现ApplicationListener接口,并在Spring配置文件中配置即可。

public class MyEventListener implements ApplicationListener {

    @Override
    public void onApplicationEvent(ApplicationEvent event) {
        //do something
    }
}

在Spring配置文件中添加如下配置:


删除ApplicationListener同样简单,只需要将实现ApplicationListener接口的类从Spring配置文件中删除即可。

三、ApplicationListener的作用

ApplicationListener可以处理各类应用程序事件,如ApplicationContext、ServletRequest、HttpSession等

1、ApplicationContext事件:监听应用程序上下文的启动和关闭事件,并可以对应用程序上下文进行自定义的扩展。

public class MyContextListener implements ApplicationListener {

    @Override
    public void onApplicationEvent(ContextStartedEvent event) {
        ApplicationContext context = event.getApplicationContext();
        //do something with context
    }
}

2、ServletRequest事件:监听servlet请求事件,可以对HttpServletRequest和HttpServletResponse进行自定义的扩展。

public class MyRequestListener implements ApplicationListener {

    @Override
    public void onApplicationEvent(ServletRequestEvent event) {
        HttpServletRequest request = (HttpServletRequest) event.getServletRequest();
        HttpServletResponse response = (HttpServletResponse) event.getServletResponse();
        //do something with request and/or response
    }
}

3、HttpSession事件:监听HttpSession的创建、销毁、属性变更等事件。

public class MySessionListener implements ApplicationListener {

    @Override
    public void onApplicationEvent(HttpSessionEvent event) {
        HttpSession session = event.getSession();
        //do something with session
    }
}

四、ApplicationListener的用法

ApplicationListener可用于编写各类系统插件和监听器,可以独立于应用程序自身。

举一个应用场景的例子,一个电商平台在用户下单完成后,需要将订单信息发送给短信平台,以便发送短信给用户,通知订单提交成功。

第一步:定义事件

public class OrderEvent extends ApplicationEvent {
    private String orderNo;
    private String mobile;

    public OrderEvent(Object source, String orderNo, String mobile) {
        super(source);
        this.orderNo = orderNo;
        this.mobile = mobile;
    }

    public String getOrderNo() {
        return orderNo;
    }

    public String getMobile() {
        return mobile;
    }
}

第二步:编写监听器

public class SmsListener implements ApplicationListener {

    @Override
    public void onApplicationEvent(OrderEvent event) {
        String orderNo = event.getOrderNo();
        String mobile = event.getMobile();
        //send sms to mobile with orderNo
    }
}

第三步:发布事件

public class OrderService {
    @Autowired
    private ApplicationContext ctx;

    public void submitOrder(String orderNo, String mobile) {
        //do something
        OrderEvent event = new OrderEvent(this, orderNo, mobile);
        ctx.publishEvent(event);
    }
}

在订单提交成功后调用OrderService的submitOrder方法,然后就能发送短信给用户了。

五、ApplicationListener不执行

在某些情况下,需要限制应用程序事件的执行。有两种方法可以做到这一点:

1、在事件监听器中进行判断,当不满足条件时不执行事件

public class MyEventListener implements ApplicationListener {

    @Override
    public void onApplicationEvent(SomeEvent event) {
        if(/* condition not met */){
            return;
        }
        //do something
    }
}

2、使用条件注解,只有满足条件时才会启用事件监听器

@Conditional(MyCondition.class)
public class MyEventListener implements ApplicationListener {

    @Override
    public void onApplicationEvent(SomeEvent event) {
        //do something
    }
}

public class MyCondition implements Condition {

    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        //return true or false based on some condition
    }
}

六、ApplicationListener加载两次

在Spring应用程序中,有些情况下,同一个ApplicationListener会被加载多次,导致事件执行多次。针对这种情况,有以下两种解决方案:

1、将ApplicationListener注册为单例模式


2、在Spring配置文件中启用事件多播器,将ApplicationListener注册到多播器中


    





七、ApplicationListener指定执行顺序

在一个Spring应用程序中,有可能存在多个ApplicationListener对同一事件同时进行监听。当需要保证它们的执行顺序时,可以使用@Order注解来指定它们的执行顺序。

@Order(1)
public class MyFirstEventListener implements ApplicationListener {
    //do something
}

@Order(2)
public class MySecondEventListener implements ApplicationListener {
    //do something
}

@Order(3)
public class MyThirdEventListener implements ApplicationListener {
    //do something
}

八、ApplicationListener阻止程序启动

在某些情况下,需要在Spring应用程序启动过程中进行一些自定义的验证和检查,如果不通过则需要阻止程序启动。可以实现ApplicationListener接口的onApplicationEvent方法,并在检查失败时抛出异常,即可阻止程序的启动。

public class MyContextListener implements ApplicationListener {

    @Override
    public void onApplicationEvent(ContextRefreshedEvent event) {
        //do some checks
        if(/*check failed*/){
            throw new RuntimeException("Failed to start application");
        }
    }
}

九、ApplicationListenerDetector

ApplicationListenerDetector用于动态扫描项目中已经实现ApplicationListener接口的类,并将这些类自动注册到Spring的ApplicationContext中成为监听器。


    

以上是ApplicationListener的详解,可以看到它的使用非常广泛。通过ApplicationListener可以自定义应用程序事件及其相应的处理逻辑,可以使用AOP方式,实现应用程序的各项业务逻辑。使用Spring面向切面编程(AOP),可以为应用程序添加上更多的可重用性、扩展性、松散耦合性。

原创文章,作者:小蓝,如若转载,请注明出处:https://www.506064.com/n/151667.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
小蓝小蓝
上一篇 2024-11-11 13:43
下一篇 2024-11-11 13:43

相关推荐

  • Linux sync详解

    一、sync概述 sync是Linux中一个非常重要的命令,它可以将文件系统缓存中的内容,强制写入磁盘中。在执行sync之前,所有的文件系统更新将不会立即写入磁盘,而是先缓存在内存…

    编程 2025-04-25
  • 神经网络代码详解

    神经网络作为一种人工智能技术,被广泛应用于语音识别、图像识别、自然语言处理等领域。而神经网络的模型编写,离不开代码。本文将从多个方面详细阐述神经网络模型编写的代码技术。 一、神经网…

    编程 2025-04-25
  • Python安装OS库详解

    一、OS简介 OS库是Python标准库的一部分,它提供了跨平台的操作系统功能,使得Python可以进行文件操作、进程管理、环境变量读取等系统级操作。 OS库中包含了大量的文件和目…

    编程 2025-04-25
  • Python输入输出详解

    一、文件读写 Python中文件的读写操作是必不可少的基本技能之一。读写文件分别使用open()函数中的’r’和’w’参数,读取文件…

    编程 2025-04-25
  • C语言贪吃蛇详解

    一、数据结构和算法 C语言贪吃蛇主要运用了以下数据结构和算法: 1. 链表 typedef struct body { int x; int y; struct body *nex…

    编程 2025-04-25
  • Linux修改文件名命令详解

    在Linux系统中,修改文件名是一个很常见的操作。Linux提供了多种方式来修改文件名,这篇文章将介绍Linux修改文件名的详细操作。 一、mv命令 mv命令是Linux下的常用命…

    编程 2025-04-25
  • MPU6050工作原理详解

    一、什么是MPU6050 MPU6050是一种六轴惯性传感器,能够同时测量加速度和角速度。它由三个传感器组成:一个三轴加速度计和一个三轴陀螺仪。这个组合提供了非常精细的姿态解算,其…

    编程 2025-04-25
  • Java BigDecimal 精度详解

    一、基础概念 Java BigDecimal 是一个用于高精度计算的类。普通的 double 或 float 类型只能精确表示有限的数字,而对于需要高精度计算的场景,BigDeci…

    编程 2025-04-25
  • git config user.name的详解

    一、为什么要使用git config user.name? git是一个非常流行的分布式版本控制系统,很多程序员都会用到它。在使用git commit提交代码时,需要记录commi…

    编程 2025-04-25
  • nginx与apache应用开发详解

    一、概述 nginx和apache都是常见的web服务器。nginx是一个高性能的反向代理web服务器,将负载均衡和缓存集成在了一起,可以动静分离。apache是一个可扩展的web…

    编程 2025-04-25

发表回复

登录后才能评论