解析Spring事件发布与监听机制

前言

Spring 提供了 ApplicationContext 事件机制,可以发布和监听事件,这个特性非常有用。

Spring 内置了一些事件和监听器,例如在 Spring 容器启动前,Spring 容器启动后,应用启动失败后等事件发生后,监听在这些事件上的监听器会做出相应的响应处理。

当然,我们也可以自定义监听器,监听 Spring 原有的事件。或者自定义我们自己的事件和监听器,在必要的时间点发布事件,然后监听器监听到事件就做出响应处理。

ApplicationContext 事件机制

ApplicationContext 事件机制采用观察者设计模式来实现,通过 ApplicationEvent 事件类和 ApplicationListener 监听器接口,可以实现 ApplicationContext 事件发布与处理。

每当 ApplicationContext 发布 ApplicationEvent 时,如果 Spring 容器中有 ApplicationListener bean,则监听器会被触发执行相应的处理。当然,ApplicationEvent 事件的发布需要显示触发,要么 Spring 显示触发,要么我们显示触发。

ApplicationListener 监听器

定义应用监听器需要实现的接口。此接口继承了 JDK 标准的事件监听器接口 EventListener,EventListener 接口是一个空的标记接口,推荐所有事件监听器必须要继承它。

package org.springframework.context;

import java.util.EventListener;

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

	/**
	 * 处理应用事件
	 */
	void onApplicationEvent(E event);
}
package java.util;

public interface EventListener {
}

ApplicationListener 是个泛型接口,我们自定义此接口的实现类时,如果指定了泛型的具体事件类,那么只会监听此事件。如果不指定具体的泛型,则会监听 ApplicationEvent 抽象类的所有子类事件。

如下我们定义一个监听器,监听具体的事件,例如监听 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);
    }
}

启动服务,会发现在服务启动后,此监听器被触发了。

如果不指定具体的泛型类,则会监听 ApplicationEvent 抽象类的所有子类事件。如下所示:

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);
    }
}

注意,监听器类的 bean 要注入到 Spring 容器中,不然不会生效。一种是使用注解注入,例如 @Component。另外可以使用 SpringApplicationBuilder.listeners() 方法添加,不过这两种方式有区别的,看以下示例。

首先我们使用 @Component 注解方式,服务启动时,监视到了2个事件:

  • 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() 方法添加监听器,服务启动时,监听到了5个事件:

  • 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);
    }
}

其实这是和监听器 bean 注册的时机有关,@component 注解的监听器 bean 只有在 bean 初始化注册完后才能使用;而通过 SpringApplicationBuilder.listeners() 添加的监听器 bean 是在容器启动前,所以监听到的事件比较多。但是注意,这两个不要同时使用,不然监听器会重复执行两遍。

如果你想在监听器 bean 中注入其他 bean(例如 @Autowired),那最好是使用注解形式,因为如果太早发布监听器,可能其他 bean 还未初始化完成,可能会报错。

ApplicationEvent 事件



ApplicationEvent 是所有应用事件需要继承的抽象类。它继承了 EventObject 类,EventObject 是所有事件的根类,这个类有个 Object 类型的对象 source,代表事件源。所有继承它的类的构造函数都必须要显示传递这个事件源。

package org.springframework.context;

import java.util.EventObject;

public abstract class ApplicationEvent extends EventObject {

	private static final long serialVersionUID = 7099057708183571937L;

	// 发布事件的系统时间
	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 中,比较重要的事件类是 SpringApplicationEvent。Spring 有一些内置的事件,当完成某种操作时会触发某些事件。这些内置事件继承 SpringApplicationEvent 抽象类。SpringApplicationEvent 继承 ApplicationEvent 并增加了字符串数组参数字段 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;
	}
}

我们可以编写自己的监听器,然后监听这些事件,实现自己的业务逻辑。例如编写 ApplicationListener 接口的实现类,监听 ContextStartedEvent 事件,当应用容器 ApplicationContext 启动时,会发布该事件,所以我们编写的监听器会被触发。

  • ContextRefreshedEvent:ApplicationContext 被初始化或刷新时,事件被发布。ConfigurableApplicationContext接口中的 refresh() 方法被调用也会触发事件发布。初始化是指所有的 Bean 被成功装载,后处理 Bean 被检测并激活,所有单例 Bean 被预实例化,ApplicationContext 容器已就绪可用。
  • ContextStartedEvent:应用程序上下文被刷新后,但在任何 ApplicationRunner 和 CommandLineRunner 被调用之前,发布此事件。
  • ApplicationReadyEvent:此事件会尽可能晚地被发布,以表明应用程序已准备好为请求提供服务。事件源是SpringApplication 本身,但是要注意修改它的内部状态,因为到那时所有初始化步骤都已经完成了。
  • ContextStoppedEvent:ConfigurableApplicationContext 接口的 stop() 被调用停止 ApplicationContext 时,事件被发布。
  • ContextClosedEvent:ConfigurableApplicationContext 接口的 close() 被调用关闭 ApplicationContext 时,事件被发布。注意,一个已关闭的上下文到达生命周期末端后,它不能被刷新或重启。
  • ApplicationFailedEvent:当应用启动失败后发布事件。
  • ApplicationEnvironmentPreparedEvent:事件是在 SpringApplication 启动时发布的,并且首次检查和修改 Environment 时,此时上 ApplicationContext 还没有创建。
  • ApplicationPreparedEvent:事件发布时,SpringApplication 正在启动,ApplicationContext 已经完全准备好,但没有刷新。在这个阶段,将加载 bean definitions 并准备使用 Environment。
  • RequestHandledEvent:这是一个 web 事件,只能应用于使用 DispatcherServlet 的 Web 应用。在使用 Spring 作为前端的 MVC 控制器时,当 Spring 处理用户请求结束后,系统会自动触发该事件。

自定义事件和监听器



前面介绍了自定义监听器,然后监听 Spring 原有的事件。下面介绍自定义事件和自定义监听器,然后在程序中发布事件,触发监听器执行,实现自己的业务逻辑。

首先自定义事件,继承 ApplicationEvent,当然事件可以自定义自己的属性。

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 + '}';
    }
}

然后自定义监听器,监听我们自定义的事件。

package com.chenpi;

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

/**
 * @Description 自定义监听器
 * @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);
    }
}

注册监听器和发布事件。注册监听器上面讲解了有两种方式。事件的发布可以通过 ApplicationEventPublisher.publishEvent() 方法。此处演示直接用 configurableApplicationContext 发布,它实现了 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);
        // 注册监听器
        SpringApplication app = new SpringApplicationBuilder(Application.class)
                .listeners(new MyApplicationListener()).build();
        ConfigurableApplicationContext configurableApplicationContext = app.run(args);
        // 方便演示,在项目启动后发布事件,当然也可以在其他操作和其他时间点发布事件
        configurableApplicationContext
                .publishEvent(new MyApplicationEvent("我是事件源,项目启动成功后发布事件", "我是自定义事件属性"));
    }
}

启动服务,结果显示确实监听到发布的事件了。

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=我是事件源,项目启动成功后发布事件
}

事件监听机制能达到分发,解耦效果。例如可以在业务类中发布事件,让监听在此事件的监听器执行自己的业务处理。例如:

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("我是事件源", "我是自定义事件属性"));
    }
}

注解式监听器



除了实现 ApplicationListener 接口创建监听器外,Spring 还提供了注解 @EventListener 来创建监听器。

package com.chenpi;

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

import lombok.extern.slf4j.Slf4j;

/**
 * @Description 自定义监听器
 * @Author 陈皮
 * @Date 2021/6/26
 * @Version 1.0
 */
@Slf4j
@Component
public class MyApplicationListener01 {
    @EventListener
    public void onApplicationEvent(MyApplicationEvent event) {
        log.info(">>> MyApplicationListener:{}", event);
    }
}

而且注解还可以通过条件过滤只监听指定条件的事件。例如事件的 myField 属性的值等于"陈皮"的事件。

package com.chenpi;

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

import lombok.extern.slf4j.Slf4j;

/**
 * @Description 自定义监听器
 * @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);
    }
}

还可以在同一个类中定义多个监听,对同一个事件的不同监听还可以指定顺序。order 值越小越先执行。

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 自定义监听器
 * @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);
    }
}

执行结果如下:

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

事件的监听处理是同步的,如下:

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");
    }
}

执行结果如下:

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

不过,我们也可以显示指定异步方式去执行监听器,记得在服务添加 @EnableAsync 注解开启异步注解。

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 自定义监听器
 * @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);
    }
}

执行结果如下,注意打印的线程名。

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
}

到此这篇关于Spring事件发布与监听机制的文章就介绍到这了,更多相关Spring事件监听机制内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Spring的事件监听机制示例详解

    前言 最近公司在重构广告系统,其中核心的打包功由广告系统调用,即对apk打包的调用和打包完成之后的回调,需要提供相应的接口给广告系统.因此,为了将apk打包的核心流程和对接广告系统的业务解耦,利用了spring的事件监听特性来满足需求.以下说明spring的事件机制的相关内容. 首先spring事件分为事件发布者(EventPublisher).事件监听者(EventListener),还包括一个事件广播者(这个是spring实现相关,这一节不讨论).使用spring事件机制,需要自定义事件发布

  • 详解SpringBoot 发布ApplicationEventPublisher和监听ApplicationEvent事件

    资料地址 Spring @Aync 实现方法 自定义需要发布的事件类,需要继承ApplicationEvent类或PayloadApplicationEvent<T>(该类也仅仅是对ApplicationEvent的一层封装) 使用@EventListener来监听事件 使用ApplicationEventPublisher来发布自定义事件(@Autowired注入即可) /** * 自定义保存事件 * @author peter * 2019/1/27 14:59 */ public cla

  • 详解基于Spring Data的领域事件发布

    领域事件发布是一个领域对象为了让其它对象知道自己已经处理完成某个操作时发出的一个通知,事件发布力求从代码层面让自身对象与外部对象解耦,并减少技术代码入侵. 一. 手动发布事件 // 实体定义 @Entity public class Department implements Serializable { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Integer departmentId; @Enumerate

  • 解析Spring事件发布与监听机制

    前言 Spring 提供了 ApplicationContext 事件机制,可以发布和监听事件,这个特性非常有用. Spring 内置了一些事件和监听器,例如在 Spring 容器启动前,Spring 容器启动后,应用启动失败后等事件发生后,监听在这些事件上的监听器会做出相应的响应处理. 当然,我们也可以自定义监听器,监听 Spring 原有的事件.或者自定义我们自己的事件和监听器,在必要的时间点发布事件,然后监听器监听到事件就做出响应处理. ApplicationContext 事件机制 Ap

  • 详解Spring事件发布与监听机制

    目录 一.ApplicationContext 事件机制 二.ApplicationListener 监听器 三.ApplicationEvent 事件 四.自定义事件和监听器 五.注解式监听器 一.ApplicationContext 事件机制 ApplicationContext 事件机制采用观察者设计模式来实现,通过 ApplicationEvent 事件类和 ApplicationListener 监听器接口,可以实现 ApplicationContext 事件发布与处理. 每当 App

  • SpringBoot事件发布和监听详解

    目录 概述 事件监听的结构 Publisher,Event和Listener的关系 事件 发布者 监听者 总结 概述 ApplicationEvent以及Listener是Spring为我们提供的一个事件监听.订阅的实现,内部实现原理是观察者设计模式,设计初衷也是为了系统业务逻辑之间的解耦,提高可扩展性以及可维护性.事件发布者并不需要考虑谁去监听,监听具体的实现内容是什么,发布者的工作只是为了发布事件而已.事件监听的作用与消息队列有一点类似. 事件监听的结构 主要有三个部分组成: 发布者Publ

  • Spring事件发布监听,顺序监听,异步监听方式

    目录 1. Spring的事件通知 2. Spring事件通知使用 2.1 Spring的事件 2.2 事件监听 2.2.1 接口方式实现 2.2.2 注解实现 2.3 事件发布 2.4 Spring顺序监听器 2.5 异步监听 3. 总结 最近在做公司的业务需要用到事件通知,比如启动成功打印日志,通知其他业务做相应的操作,就用到了Spring的事件通知机制. 1. Spring的事件通知 Spring的事件通知本质上就是发布-订阅,即生产者-消费者:体现了观察者设计模式或者回调通知,那么Spr

  • Spring事件监听机制观察者模式详解

    目录 前言 观察者模式 观察者的角色定义 Java中的事件机制 Spring中的事件机制 Spring事件监听案例 小结 前言 Spring中提供了一套默认的事件监听机制,在容器初始化时便使用了这套机制.同时,Spring也提供了事件监听机制的接口扩展能力,开发者基于此可快速实现自定义的事件监听功能. Spring的事件监听机制是在JDK事件监听的基础上进行的扩展,也是在典型观察者模式上的进一步抽象和改进.所以,结合Spring的事件监听机制与观察者模式来学习,可以达到理论与实践的完美融合. 本

  • 详谈Java中的事件监听机制

    鼠标事件监听机制的三个方面: 1.事件源对象: 事件源对象就是能够产生动作的对象.在Java语言中所有的容器组件和元素组件都是事件监听中的事件源对象.Java中根据事件的动作来区分不同的事件源对象,动作发生在哪个组件上,那么该组件就是事件源对象 2.事件监听方法: addMouseListener(MouseListener ml) ;该方法主要用来捕获鼠标的释放,按下,点击,进入和离开的动作:捕获到相应的动作后,交由事件处理类(实现MouseListener接口)进行处理. addAction

  • .NET事件监听机制的局限与扩展分析

    本文实例分析了.NET事件监听机制的局限与扩展.分享给大家供大家参考.具体分析如下: .NET中把"事件"看作一个基本的编程概念,并提供了非常优美的语法支持,对比如下C#和Java代码可以看出两种语言设计思想之间的差异. 复制代码 代码如下: // C# someButton.Click += OnSomeButtonClick; 复制代码 代码如下: // Java someButton.addActionListener(     new ActionListener(){    

  • Vue 组件事件触发和监听实现源码解析

    目录 正文 Vue 的事件触发和监听 源码分析 on once emit off 动手实现 总结 正文 通常我们在使用Vue的时候,会使用$emit和$on来触发和监听事件,但是有没有思考是如何实现的呢? 今天带来的是一个微型的事件触发的库,借它们的源码来简单初步了解Vue的事件触发和监听的实现. mitt tiny-emitter mitt使用TypeScript编写,tiny-emitter使用原生ES5编写,两者对比tiny-emitter功能稍微丰富一写,所以直接看tiny-emitte

  • JavaGUI事件监听机制超详细讲解

    1.一个事件模型中有上对象:事件源,事件以及监听程序 2.事件监听机制: 事件源        事件发生的地方 事件            要发生的事情 事件处理     针对发生的事情做出的处理方案 事件监听     把事件源和事件关联起来 使用步骤: 新建一个组件(如 JButton) 将该组件添加到相应的面板(如 JFrame) 注册监听器以监听事件源产生的事件(如通过ActionListener来响应用户点击按钮) 定义处理事件的方法(如在ActionListener中的actionPe

  • Java事件监听机制讲解

    给组件加上监听器 定义一个类,这个类继承ActionListener pubulic class ButListener implements ActionListener{ Public void actionPerformed(ActionEvent e){ }} 给按钮添加动作监听器方法 ButListener but = new ButListen(); jbu.addActionListener(but); 加上监听机制后再监听器ButListener时间处理方法中再创建窗口即可得到点

随机推荐