最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

解析Spring事件發(fā)布與監(jiān)聽(tīng)機(jī)制

 更新時(shí)間:2021年06月28日 10:39:06   作者:陳皮的JavaLib  
本篇文章給大家介紹Spring事件發(fā)布與監(jiān)聽(tīng)機(jī)制,通過(guò) ApplicationEvent 事件類(lèi)和 ApplicationListener 監(jiān)聽(tīng)器接口,可以實(shí)現(xiàn) ApplicationContext 事件發(fā)布與處理,需要的朋友參考下吧

前言

Spring 提供了 ApplicationContext 事件機(jī)制,可以發(fā)布和監(jiān)聽(tīng)事件,這個(gè)特性非常有用。

Spring 內(nèi)置了一些事件和監(jiān)聽(tīng)器,例如在 Spring 容器啟動(dòng)前,Spring 容器啟動(dòng)后,應(yīng)用啟動(dòng)失敗后等事件發(fā)生后,監(jiān)聽(tīng)在這些事件上的監(jiān)聽(tīng)器會(huì)做出相應(yīng)的響應(yīng)處理。

當(dāng)然,我們也可以自定義監(jiān)聽(tīng)器,監(jiān)聽(tīng) Spring 原有的事件?;蛘咦远x我們自己的事件和監(jiān)聽(tīng)器,在必要的時(shí)間點(diǎn)發(fā)布事件,然后監(jiān)聽(tīng)器監(jiān)聽(tīng)到事件就做出響應(yīng)處理。

ApplicationContext 事件機(jī)制

ApplicationContext 事件機(jī)制采用觀察者設(shè)計(jì)模式來(lái)實(shí)現(xiàn),通過(guò) ApplicationEvent 事件類(lèi)和 ApplicationListener 監(jiān)聽(tīng)器接口,可以實(shí)現(xiàn) ApplicationContext 事件發(fā)布與處理。

每當(dāng) ApplicationContext 發(fā)布 ApplicationEvent 時(shí),如果 Spring 容器中有 ApplicationListener bean,則監(jiān)聽(tīng)器會(huì)被觸發(fā)執(zhí)行相應(yīng)的處理。當(dāng)然,ApplicationEvent 事件的發(fā)布需要顯示觸發(fā),要么 Spring 顯示觸發(fā),要么我們顯示觸發(fā)。

ApplicationListener 監(jiān)聽(tīng)器

定義應(yīng)用監(jiān)聽(tīng)器需要實(shí)現(xiàn)的接口。此接口繼承了 JDK 標(biāo)準(zhǔn)的事件監(jiān)聽(tīng)器接口 EventListener,EventListener 接口是一個(gè)空的標(biāo)記接口,推薦所有事件監(jiān)聽(tīng)器必須要繼承它。

package org.springframework.context;

import java.util.EventListener;

@FunctionalInterface
public interface ApplicationListener<E extends ApplicationEvent> extends EventListener {

	/**
	 * 處理應(yīng)用事件
	 */
	void onApplicationEvent(E event);
}
package java.util;

public interface EventListener {
}

ApplicationListener 是個(gè)泛型接口,我們自定義此接口的實(shí)現(xiàn)類(lèi)時(shí),如果指定了泛型的具體事件類(lèi),那么只會(huì)監(jiān)聽(tīng)此事件。如果不指定具體的泛型,則會(huì)監(jiān)聽(tīng) ApplicationEvent 抽象類(lèi)的所有子類(lèi)事件。

如下我們定義一個(gè)監(jiān)聽(tīng)器,監(jiān)聽(tīng)具體的事件,例如監(jiān)聽(tīng) ApplicationStartedEvent 事件。

package com.chenpi;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.context.event.ApplicationStartedEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;

/**
 * @Description
 * @Author 陳皮
 * @Date 2021/6/26
 * @Version 1.0
 */
@Slf4j
@Component
public class MyApplicationListener implements ApplicationListener<ApplicationStartedEvent> {
    @Override
    public void onApplicationEvent(ApplicationStartedEvent event) {
        log.info(">>> MyApplicationListener:{}", event);
    }
}

啟動(dòng)服務(wù),會(huì)發(fā)現(xiàn)在服務(wù)啟動(dòng)后,此監(jiān)聽(tīng)器被觸發(fā)了。

在這里插入圖片描述

如果不指定具體的泛型類(lèi),則會(huì)監(jiān)聽(tīng) ApplicationEvent 抽象類(lèi)的所有子類(lèi)事件。如下所示:

package com.chenpi;

import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;

/**
 * @Description
 * @Author 陳皮
 * @Date 2021/6/26
 * @Version 1.0
 */
@Slf4j
@Component
public class MyApplicationListener implements ApplicationListener {
    @Override
    public void onApplicationEvent(ApplicationEvent event) {
        log.info(">>> MyApplicationListener:{}", event);
    }
}

在這里插入圖片描述

注意,監(jiān)聽(tīng)器類(lèi)的 bean 要注入到 Spring 容器中,不然不會(huì)生效。一種是使用注解注入,例如 @Component。另外可以使用 SpringApplicationBuilder.listeners() 方法添加,不過(guò)這兩種方式有區(qū)別的,看以下示例。

首先我們使用 @Component 注解方式,服務(wù)啟動(dòng)時(shí),監(jiān)視到了2個(gè)事件:

  • ApplicationStartedEvent
  • ApplicationReadyEvent
package com.chenpi;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.context.event.SpringApplicationEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;

/**
 * @Description
 * @Author 陳皮
 * @Date 2021/6/26
 * @Version 1.0
 */
@Slf4j
@Component
public class MyApplicationListener implements ApplicationListener<SpringApplicationEvent> {
    @Override
    public void onApplicationEvent(SpringApplicationEvent event) {
        log.info(">>> MyApplicationListener:{}", event);
    }
}

在這里插入圖片描述

而使用 SpringApplicationBuilder.listeners() 方法添加監(jiān)聽(tīng)器,服務(wù)啟動(dòng)時(shí),監(jiān)聽(tīng)到了5個(gè)事件:

  • ApplicationEnvironmentPreparedEvent
  • ApplicationContextInitializedEvent
  • ApplicationPreparedEvent
  • ApplicationStartedEvent
  • ApplicationReadyEvent
package com.chenpi;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.context.ConfigurableApplicationContext;

@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        // SpringApplication.run(Application.class, args);

        SpringApplication app = new SpringApplicationBuilder(Application.class)
                .listeners(new MyApplicationListener()).build();
        app.run(args);
    }
}

在這里插入圖片描述

其實(shí)這是和監(jiān)聽(tīng)器 bean 注冊(cè)的時(shí)機(jī)有關(guān),@component 注解的監(jiān)聽(tīng)器 bean 只有在 bean 初始化注冊(cè)完后才能使用;而通過(guò) SpringApplicationBuilder.listeners() 添加的監(jiān)聽(tīng)器 bean 是在容器啟動(dòng)前,所以監(jiān)聽(tīng)到的事件比較多。但是注意,這兩個(gè)不要同時(shí)使用,不然監(jiān)聽(tīng)器會(huì)重復(fù)執(zhí)行兩遍。

如果你想在監(jiān)聽(tīng)器 bean 中注入其他 bean(例如 @Autowired),那最好是使用注解形式,因?yàn)槿绻绨l(fā)布監(jiān)聽(tīng)器,可能其他 bean 還未初始化完成,可能會(huì)報(bào)錯(cuò)。

ApplicationEvent 事件


ApplicationEvent 是所有應(yīng)用事件需要繼承的抽象類(lèi)。它繼承了 EventObject 類(lèi),EventObject 是所有事件的根類(lèi),這個(gè)類(lèi)有個(gè) Object 類(lèi)型的對(duì)象 source,代表事件源。所有繼承它的類(lèi)的構(gòu)造函數(shù)都必須要顯示傳遞這個(gè)事件源。

package org.springframework.context;

import java.util.EventObject;

public abstract class ApplicationEvent extends EventObject {

	private static final long serialVersionUID = 7099057708183571937L;

	// 發(fā)布事件的系統(tǒng)時(shí)間
	private final long timestamp;

	public ApplicationEvent(Object source) {
		super(source);
		this.timestamp = System.currentTimeMillis();
	}

	public final long getTimestamp() {
		return this.timestamp;
	}
}
package java.util;

public class EventObject implements java.io.Serializable {

    private static final long serialVersionUID = 5516075349620653480L;

    protected transient Object  source;

    public EventObject(Object source) {
        if (source == null)
            throw new IllegalArgumentException("null source");

        this.source = source;
    }

    public Object getSource() {
        return source;
    }

    public String toString() {
        return getClass().getName() + "[source=" + source + "]";
    }
}

在 Spring 中,比較重要的事件類(lèi)是 SpringApplicationEvent。Spring 有一些內(nèi)置的事件,當(dāng)完成某種操作時(shí)會(huì)觸發(fā)某些事件。這些內(nèi)置事件繼承 SpringApplicationEvent 抽象類(lèi)。SpringApplicationEvent 繼承 ApplicationEvent 并增加了字符串?dāng)?shù)組參數(shù)字段 args。

/**
 * Base class for {@link ApplicationEvent} related to a {@link SpringApplication}.
 *
 * @author Phillip Webb
 * @since 1.0.0
 */
@SuppressWarnings("serial")
public abstract class SpringApplicationEvent extends ApplicationEvent {

	private final String[] args;

	public SpringApplicationEvent(SpringApplication application, String[] args) {
		super(application);
		this.args = args;
	}

	public SpringApplication getSpringApplication() {
		return (SpringApplication) getSource();
	}

	public final String[] getArgs() {
		return this.args;
	}
}

在這里插入圖片描述

我們可以編寫(xiě)自己的監(jiān)聽(tīng)器,然后監(jiān)聽(tīng)這些事件,實(shí)現(xiàn)自己的業(yè)務(wù)邏輯。例如編寫(xiě) ApplicationListener 接口的實(shí)現(xiàn)類(lèi),監(jiān)聽(tīng) ContextStartedEvent 事件,當(dāng)應(yīng)用容器 ApplicationContext 啟動(dòng)時(shí),會(huì)發(fā)布該事件,所以我們編寫(xiě)的監(jiān)聽(tīng)器會(huì)被觸發(fā)。

  • ContextRefreshedEvent:ApplicationContext 被初始化或刷新時(shí),事件被發(fā)布。ConfigurableApplicationContext接口中的 refresh() 方法被調(diào)用也會(huì)觸發(fā)事件發(fā)布。初始化是指所有的 Bean 被成功裝載,后處理 Bean 被檢測(cè)并激活,所有單例 Bean 被預(yù)實(shí)例化,ApplicationContext 容器已就緒可用。
  • ContextStartedEvent:應(yīng)用程序上下文被刷新后,但在任何 ApplicationRunner 和 CommandLineRunner 被調(diào)用之前,發(fā)布此事件。
  • ApplicationReadyEvent:此事件會(huì)盡可能晚地被發(fā)布,以表明應(yīng)用程序已準(zhǔn)備好為請(qǐng)求提供服務(wù)。事件源是SpringApplication 本身,但是要注意修改它的內(nèi)部狀態(tài),因?yàn)榈侥菚r(shí)所有初始化步驟都已經(jīng)完成了。
  • ContextStoppedEvent:ConfigurableApplicationContext 接口的 stop() 被調(diào)用停止 ApplicationContext 時(shí),事件被發(fā)布。
  • ContextClosedEvent:ConfigurableApplicationContext 接口的 close() 被調(diào)用關(guān)閉 ApplicationContext 時(shí),事件被發(fā)布。注意,一個(gè)已關(guān)閉的上下文到達(dá)生命周期末端后,它不能被刷新或重啟。
  • ApplicationFailedEvent:當(dāng)應(yīng)用啟動(dòng)失敗后發(fā)布事件。
  • ApplicationEnvironmentPreparedEvent:事件是在 SpringApplication 啟動(dòng)時(shí)發(fā)布的,并且首次檢查和修改 Environment 時(shí),此時(shí)上 ApplicationContext 還沒(méi)有創(chuàng)建。
  • ApplicationPreparedEvent:事件發(fā)布時(shí),SpringApplication 正在啟動(dòng),ApplicationContext 已經(jīng)完全準(zhǔn)備好,但沒(méi)有刷新。在這個(gè)階段,將加載 bean definitions 并準(zhǔn)備使用 Environment。
  • RequestHandledEvent:這是一個(gè) web 事件,只能應(yīng)用于使用 DispatcherServlet 的 Web 應(yīng)用。在使用 Spring 作為前端的 MVC 控制器時(shí),當(dāng) Spring 處理用戶請(qǐng)求結(jié)束后,系統(tǒng)會(huì)自動(dòng)觸發(fā)該事件。

自定義事件和監(jiān)聽(tīng)器


前面介紹了自定義監(jiān)聽(tīng)器,然后監(jiān)聽(tīng) Spring 原有的事件。下面介紹自定義事件和自定義監(jiān)聽(tīng)器,然后在程序中發(fā)布事件,觸發(fā)監(jiān)聽(tīng)器執(zhí)行,實(shí)現(xiàn)自己的業(yè)務(wù)邏輯。

首先自定義事件,繼承 ApplicationEvent,當(dāng)然事件可以自定義自己的屬性。

package com.chenpi;

import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import org.springframework.context.ApplicationEvent;

/**
 * @Description 自定義事件
 * @Author 陳皮
 * @Date 2021/6/26
 * @Version 1.0
 */
@Getter
@Setter
public class MyApplicationEvent extends ApplicationEvent {

    // 事件可以增加自己的屬性
    private String myField;

    public MyApplicationEvent(Object source, String myField) {
        // 綁定事件源
        super(source);
        this.myField = myField;
    }

    @Override
    public String toString() {
        return "MyApplicationEvent{" + "myField='" + myField + '\'' + ", source=" + source + '}';
    }
}

然后自定義監(jiān)聽(tīng)器,監(jiān)聽(tīng)我們自定義的事件。

package com.chenpi;

import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationListener;

/**
 * @Description 自定義監(jiān)聽(tīng)器
 * @Author 陳皮
 * @Date 2021/6/26
 * @Version 1.0
 */
@Slf4j
public class MyApplicationListener implements ApplicationListener<MyApplicationEvent> {
    @Override
    public void onApplicationEvent(MyApplicationEvent event) {
        log.info(">>> MyApplicationListener:{}", event);
    }
}

注冊(cè)監(jiān)聽(tīng)器和發(fā)布事件。注冊(cè)監(jiān)聽(tīng)器上面講解了有兩種方式。事件的發(fā)布可以通過(guò) ApplicationEventPublisher.publishEvent() 方法。此處演示直接用 configurableApplicationContext 發(fā)布,它實(shí)現(xiàn)了 ApplicationEventPublisher 接口。

package com.chenpi;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.context.ConfigurableApplicationContext;

@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        // SpringApplication.run(Application.class, args);
        // 注冊(cè)監(jiān)聽(tīng)器
        SpringApplication app = new SpringApplicationBuilder(Application.class)
                .listeners(new MyApplicationListener()).build();
        ConfigurableApplicationContext configurableApplicationContext = app.run(args);
        // 方便演示,在項(xiàng)目啟動(dòng)后發(fā)布事件,當(dāng)然也可以在其他操作和其他時(shí)間點(diǎn)發(fā)布事件
        configurableApplicationContext
                .publishEvent(new MyApplicationEvent("我是事件源,項(xiàng)目啟動(dòng)成功后發(fā)布事件", "我是自定義事件屬性"));
    }
}

啟動(dòng)服務(wù),結(jié)果顯示確實(shí)監(jiān)聽(tīng)到發(fā)布的事件了。

2021-06-26 16:15:09.584  INFO 10992 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8081 (http) with context path ''
2021-06-26 16:15:09.601  INFO 10992 --- [           main] com.chenpi.Application                   : Started Application in 2.563 seconds (JVM running for 4.012)
2021-06-26 16:15:09.606  INFO 10992 --- [           main] com.chenpi.MyApplicationListener         : >>> MyApplicationListener:MyApplicationEvent{myField='我是自定義事件屬性', source=我是事件源,項(xiàng)目啟動(dòng)成功后發(fā)布事件
}

事件監(jiān)聽(tīng)機(jī)制能達(dá)到分發(fā),解耦效果。例如可以在業(yè)務(wù)類(lèi)中發(fā)布事件,讓監(jiān)聽(tīng)在此事件的監(jiān)聽(tīng)器執(zhí)行自己的業(yè)務(wù)處理。例如:

package com.chenpi;

import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.stereotype.Service;

/**
 * @Description
 * @Author 陳皮
 * @Date 2021/6/26
 * @Version 1.0
 */
@Service
public class MyService implements ApplicationEventPublisherAware {

    private ApplicationEventPublisher applicationEventPublisher;

    @Override
    public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
        this.applicationEventPublisher = applicationEventPublisher;
    }

    public void testEvent() {
        applicationEventPublisher
                .publishEvent(new MyApplicationEvent("我是事件源", "我是自定義事件屬性"));
    }
}

注解式監(jiān)聽(tīng)器


除了實(shí)現(xiàn) ApplicationListener 接口創(chuàng)建監(jiān)聽(tīng)器外,Spring 還提供了注解 @EventListener 來(lái)創(chuàng)建監(jiān)聽(tīng)器。

package com.chenpi;

import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;

import lombok.extern.slf4j.Slf4j;

/**
 * @Description 自定義監(jiān)聽(tīng)器
 * @Author 陳皮
 * @Date 2021/6/26
 * @Version 1.0
 */
@Slf4j
@Component
public class MyApplicationListener01 {
    @EventListener
    public void onApplicationEvent(MyApplicationEvent event) {
        log.info(">>> MyApplicationListener:{}", event);
    }
}

而且注解還可以通過(guò)條件過(guò)濾只監(jiān)聽(tīng)指定條件的事件。例如事件的 myField 屬性的值等于"陳皮"的事件。

package com.chenpi;

import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;

import lombok.extern.slf4j.Slf4j;

/**
 * @Description 自定義監(jiān)聽(tīng)器
 * @Author 陳皮
 * @Date 2021/6/26
 * @Version 1.0
 */
@Slf4j
@Component
public class MyApplicationListener01 {
    @EventListener(condition = "#event.myField.equals('陳皮')")
    public void onApplicationEvent(MyApplicationEvent event) {
        log.info(">>> MyApplicationListener:{}", event);
    }
}

還可以在同一個(gè)類(lèi)中定義多個(gè)監(jiān)聽(tīng),對(duì)同一個(gè)事件的不同監(jiān)聽(tīng)還可以指定順序。order 值越小越先執(zhí)行。

package com.chenpi;

import org.springframework.context.event.EventListener;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import lombok.extern.slf4j.Slf4j;

/**
 * @Description 自定義監(jiān)聽(tīng)器
 * @Author 陳皮
 * @Date 2021/6/26
 * @Version 1.0
 */
@Slf4j
@Component
public class MyApplicationListener01 {
    @Order(2)
    @EventListener
    public void onApplicationEvent(MyApplicationEvent event) {
        log.info(">>> onApplicationEvent order=2:{}", event);
    }

    @Order(1)
    @EventListener
    public void onApplicationEvent01(MyApplicationEvent event) {
        log.info(">>> onApplicationEvent order=1:{}", event);
    }

    @EventListener
    public void otherEvent(YourApplicationEvent event) {
        log.info(">>> otherEvent:{}", event);
    }
}

執(zhí)行結(jié)果如下:

>>> onApplicationEvent order=1:MyApplicationEvent{myField='陳皮', source=我是事件源}
>>> onApplicationEvent order=2:MyApplicationEvent{myField='陳皮', source=我是事件源}
>>> otherEvent:MyApplicationEvent{myField='我是自定義事件屬性01', source=我是事件源01}

事件的監(jiān)聽(tīng)處理是同步的,如下:

package com.chenpi;

import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.stereotype.Service;

/**
 * @Description
 * @Author 陳皮
 * @Date 2021/6/26
 * @Version 1.0
 */
@Service
@Slf4j
public class MyService implements ApplicationEventPublisherAware {

    private ApplicationEventPublisher applicationEventPublisher;

    @Override
    public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
        this.applicationEventPublisher = applicationEventPublisher;
    }

    public void testEvent() {
        log.info(">>> testEvent begin");
        applicationEventPublisher.publishEvent(new MyApplicationEvent("我是事件源", "陳皮"));
        applicationEventPublisher.publishEvent(new YourApplicationEvent("我是事件源01", "我是自定義事件屬性01"));
        log.info(">>> testEvent end");
    }
}

執(zhí)行結(jié)果如下:

2021-06-26 20:34:27.990 INFO 12936 --- [nio-8081-exec-1] com.chenpi.MyService : >>> testEvent begin
2021-06-26 20:34:27.990 INFO 12936 --- [nio-8081-exec-1] com.chenpi.MyApplicationListener01 : >>> onApplicationEvent order=1:MyApplicationEvent{myField='陳皮', source=我是事件源}
2021-06-26 20:34:27.991 INFO 12936 --- [nio-8081-exec-1] com.chenpi.MyApplicationListener01 : >>> onApplicationEvent order=2:MyApplicationEvent{myField='陳皮', source=我是事件源}
2021-06-26 20:34:27.992 INFO 12936 --- [nio-8081-exec-1] com.chenpi.MyApplicationListener01 : >>> otherEvent:MyApplicationEvent{myField='我是自定義事件屬性01', source=我是事件源01}
2021-06-26 20:34:27.992 INFO 12936 --- [nio-8081-exec-1] com.chenpi.MyService : >>> testEvent end

不過(guò),我們也可以顯示指定異步方式去執(zhí)行監(jiān)聽(tīng)器,記得在服務(wù)添加 @EnableAsync 注解開(kāi)啟異步注解。

package com.chenpi;

import org.springframework.context.event.EventListener;
import org.springframework.core.annotation.Order;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import lombok.extern.slf4j.Slf4j;

/**
 * @Description 自定義監(jiān)聽(tīng)器
 * @Author 陳皮
 * @Date 2021/6/26
 * @Version 1.0
 */
@Slf4j
@Component
public class MyApplicationListener01 {

    @Async
    @Order(2)
    @EventListener
    public void onApplicationEvent(MyApplicationEvent event) {
        log.info(">>> onApplicationEvent order=2:{}", event);
    }

    @Order(1)
    @EventListener
    public void onApplicationEvent01(MyApplicationEvent event) {
        log.info(">>> onApplicationEvent order=1:{}", event);
    }

    @Async
    @EventListener
    public void otherEvent(YourApplicationEvent event) {
        log.info(">>> otherEvent:{}", event);
    }
}

執(zhí)行結(jié)果如下,注意打印的線程名。

2021-06-26 20:37:04.807  INFO 9092 --- [nio-8081-exec-1] com.chenpi.MyService                     : >>> testEvent begin
2021-06-26 20:37:04.819  INFO 9092 --- [nio-8081-exec-1] com.chenpi.MyApplicationListener01       : >>> onApplicationEvent order=1:MyApplicationEvent{myField='陳皮', source=我是事件源}
2021-06-26 20:37:04.831  INFO 9092 --- [         task-1] com.chenpi.MyApplicationListener01       : >>> onApplicationEvent order=2:MyApplicationEvent{myField='陳皮', source=我是事件源}
2021-06-26 20:37:04.831  INFO 9092 --- [nio-8081-exec-1] com.chenpi.MyService                     : >>> testEvent end
2021-06-26 20:37:04.831  INFO 9092 --- [         task-2] com.chenpi.MyApplicationListener01       : >>> otherEvent:MyApplicationEvent{myField='我是自定義事件屬性01', source=我是事件源01
}

到此這篇關(guān)于Spring事件發(fā)布與監(jiān)聽(tīng)機(jī)制的文章就介紹到這了,更多相關(guān)Spring事件監(jiān)聽(tīng)機(jī)制內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java字符串操作技巧之語(yǔ)法、示例與應(yīng)用場(chǎng)景分析

    Java字符串操作技巧之語(yǔ)法、示例與應(yīng)用場(chǎng)景分析

    在Java算法題和日常開(kāi)發(fā)中,字符串處理是必備的核心技能,本文全面梳理Java中字符串的常用操作語(yǔ)法,結(jié)合代碼示例、應(yīng)用場(chǎng)景和避坑指南,可快速掌握字符串處理技巧,輕松應(yīng)對(duì)筆試面試高頻題目,感興趣的朋友一起看看吧
    2025-04-04
  • 那些年用httpclient時(shí)踩過(guò)的一些坑

    那些年用httpclient時(shí)踩過(guò)的一些坑

    這篇文章主要給大家介紹了關(guān)于那些年用httpclient時(shí)踩過(guò)的一些坑,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用httpclient具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-05-05
  • SpringBoot+Mybatis plus+React實(shí)現(xiàn)條件選擇切換搜索實(shí)踐

    SpringBoot+Mybatis plus+React實(shí)現(xiàn)條件選擇切換搜索實(shí)踐

    本文主要介紹了SpringBoot+Mybatis plus+React實(shí)現(xiàn)條件選擇切換搜索實(shí)踐,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-09-09
  • 有關(guān)于整體刷新和局部刷新frameset窗口

    有關(guān)于整體刷新和局部刷新frameset窗口

    本篇小編為大家介紹有關(guān)于整體刷新和局部刷新frameset窗口的方法,希望對(duì)有需要的朋友有所幫助。
    2013-04-04
  • 使用IDEA如何拉取GitLab項(xiàng)目

    使用IDEA如何拉取GitLab項(xiàng)目

    使用IDEA拉取GitLab項(xiàng)目,首先需要組長(zhǎng)提供的socket和賬號(hào)密碼登錄內(nèi)網(wǎng)的GitLab,打開(kāi)IDEA,選擇新建項(xiàng)目,選擇Project from Version Control,然后在項(xiàng)目路徑后面添加.git,以上步驟為個(gè)人操作經(jīng)驗(yàn),希望能為大家提供參考
    2024-10-10
  • SpringBoot集成Druid連接池進(jìn)行SQL監(jiān)控的問(wèn)題解析

    SpringBoot集成Druid連接池進(jìn)行SQL監(jiān)控的問(wèn)題解析

    這篇文章主要介紹了SpringBoot集成Druid連接池進(jìn)行SQL監(jiān)控的問(wèn)題解析,在SpringBoot工程中引入Druid連接池非常簡(jiǎn)單,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2021-07-07
  • 詳解mybatis.generator配上最新的mysql 8.0.11的一些坑

    詳解mybatis.generator配上最新的mysql 8.0.11的一些坑

    這篇文章主要介紹了詳解mybatis.generator配上最新的mysql 8.0.11的一些坑,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-10-10
  • Java中二叉樹(shù)數(shù)據(jù)結(jié)構(gòu)的實(shí)現(xiàn)示例

    Java中二叉樹(shù)數(shù)據(jù)結(jié)構(gòu)的實(shí)現(xiàn)示例

    這篇文章主要介紹了Java中二叉樹(shù)數(shù)據(jù)結(jié)構(gòu)的實(shí)現(xiàn)示例,包括前中后序遍歷和求二叉樹(shù)深度的方法,需要的朋友可以參考下
    2015-08-08
  • java.util.Collections類(lèi)—emptyList()方法的使用

    java.util.Collections類(lèi)—emptyList()方法的使用

    這篇文章主要介紹了java.util.Collections類(lèi)—emptyList()方法的使用,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • Java輸出通過(guò)InetAddress獲得的IP地址數(shù)組詳細(xì)解析

    Java輸出通過(guò)InetAddress獲得的IP地址數(shù)組詳細(xì)解析

    由于byte被認(rèn)為是unsigned byte,所以最高位的1將會(huì)被解釋為符號(hào)位,另外Java中存儲(chǔ)是按照補(bǔ)碼存儲(chǔ),所以1000 0111會(huì)被認(rèn)為是補(bǔ)碼形式,轉(zhuǎn)換成原碼便是1111 0001,轉(zhuǎn)換成十進(jìn)制數(shù)便是-121
    2013-09-09

最新評(píng)論

河间市| 长阳| 太湖县| 卢湾区| 北海市| 惠安县| 梧州市| 遂平县| 儋州市| 盘山县| 东平县| 华容县| 江北区| 自治县| 汝阳县| 芦溪县| 寿光市| 大丰市| 黎川县| 寿宁县| 界首市| 晋中市| 两当县| 资中县| 郴州市| 文安县| 商丘市| 长岭县| 博湖县| 綦江县| 临颍县| 浠水县| 溧阳市| 盐池县| 岑溪市| 苗栗县| 柳州市| 大洼县| 丹江口市| 神木县| 彭州市|