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/zh-hant/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

發表回復

登錄後才能評論