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

目录
  • 一、ApplicationContext 事件机制
  • 二、ApplicationListener 监听器
  • 三、ApplicationEvent 事件
  • 四、自定义事件和监听器
  • 五、注解式监听器

一、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;

@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;

@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;

@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。

@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;

@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;

@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;

@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;

@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;

@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;

@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;

@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;

@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)

相关推荐

  • SpringBoot实现拦截器、过滤器、监听器过程解析

    这篇文章主要介绍了SpringBoot实现拦截器.过滤器.监听器过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 过滤器 过滤器简介 过滤器的英文名称为 Filter, 是 Servlet 技术中最实用的技术.如同它的名字一样,过滤器是处于客户端和服务器资源文件之间的一道过滤网,帮助我们过滤掉一些不符合要求的请求,通常用作 Session 校验,判断用户权限,如果不符合设定条件,则会被拦截到特殊的地址或者基于特殊的响应. 过滤器的使用 首

  • Spring Boot监听Redis Key失效事件实现定时任务的示例

    业务场景 我们以订单功能为例说明下: 生成订单后一段时间不支付订单会自动关闭.最简单的想法是设置定时任务轮询,但是每个订单的创建时间不一样,定时任务的规则无法设定,如果将定时任务执行的间隔设置的过短,太影响效率. 还有一种想法,在用户进入订单界面的时候,判断时间执行相关操作.方式可能有很多,在这里介绍一种监听 Redis 键值对过期时间来实现订单自动关闭. 实现思路 在生成订单时,向 Redis 中增加一个 KV 键值对,K 为订单号,保证通过 K 能定位到数据库中的某个订单即可,V 可为任意值

  • Springboot启用多个监听端口代码实例

    前段时间服务有这么个需求,web端的接口需要有web安全相关的整改,但是对内的接口并不需要.所以服务需要多个端口启动,在此记录下 代码如下 @Configuration public class EmbeddedTomcatConfiguration { @Value("${server.additionalPorts}") private String additionalPorts; @Bean public EmbeddedServletContainerFactory serv

  • SpringMVC事件监听ApplicationListener实例解析

    这篇文章主要介绍了SpringMVC事件监听ApplicationListener实例解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 1. 实现 ApplicationListener<T> 接口(T为监听类型,稍后会列出具体可监听事件) 2. 将该自定义监听类,注册为Spring容器组件.(即将该类注入Spring容器) 实例: 该类监听ServletRequestHandledEvent事件,该事件为请求结束回调事件,即一个请求完成结

  • springboot+redis过期事件监听实现过程解析

    1 修改 redis.conf配置文件: K Keyspace events, published with keyspace@ prefix事件 E Keyevent events, published with keyevent@ prefix g Generic commands (non-type specific) like DEL, EXPIRE, RENAME, - $ String commands l List commands s Set commands h Hash co

  • SpringBoot启动应用及回调监听原理解析

    这篇文章主要介绍了SpringBoot启动应用及回调监听原理解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 主类Main方法 public static void main(String[] args) { SpringApplication.run(SpringBootRunApplication.class, args); } 创建SpringApplication对象 public static ConfigurableApplica

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

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

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

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

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

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

  • SpringBoot事件发布和监听详解

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

  • 详解Apache配置多个监听端口和不同的网站目录

    详解Apache配置多个监听端口和不同的网站目录 一 :添加多端口 Listen 80 Listen 81 Listen 82 二:设置虚拟主机目录 NameVirtualHost *:80 <VirtualHost *:80> ServerName localhost DocumentRoot "D:/phpStudy/WWW/" </VirtualHost> NameVirtualHost *:81 <VirtualHost *:81> Serv

  • 详解RocketMQ 消费端如何监听消息

    目录 前言 流程地图 源码跟踪 核心模块(消息拉取) 拉取流程 拉取消息处理 当pullStatus为FOUND,消息进行提交消费的请求 消息消费进度提交 总结 前言 上一篇文章中我们主要来看RocketMQ消息消费者是如何启动的, 那他有一个步骤是非常重要的,就是启动消息的监听,通过不断的拉取消息,来实现消息的监听,那具体怎么做,让我们我们跟着源码来学习一下~ 流程地图 源码跟踪 这一块的代码比较多,我自己对关键点的一些整理,这个图我画的不是很OK 核心模块(消息拉取) 入口:this.pul

  • 详解SpringCloud eureka服务状态监听

    一.前言 近期由于公司不同平台项目之间的业务整合,需要做到相互访问! 每个平台均有自己的注册中心和服务,且注册中心相互之间并没有相互注册! 借助spring的事件监听,在eureka-server端监听服务注册,将所有服务的ip和port存放至redis库,然后让其他平台服务通过redis库获取ip和端口号,进而进行http调用.结构图如下: 二.事件解析 事件列表 在org.springframework.cloud.netflix.eureka.server.event包下会发现如下类: E

  • 详解vuex结合localstorage动态监听storage的变化

    需求:不同组件间共用同一数据,当一个组件将数据发生变化时,其他组件也可以响应该变化. 分析:vue无法监听localstorage的变化.localstorage主要用于不同页面间传值,vue适合组件间传值.对于组件间共用同一数据又想保存住信息或者再页面刷新的时候不丢失数据(vuex在页面刷新的时候存储的值会丢失,localstorage存储在本地浏览器中),可以采用vuex+localstorage的方式. 关于vuex和storage的区别 1.最重要的区别:vuex存储在内存,locals

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

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

  • 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

  • JavaScript为事件句柄绑定监听函数实例详解

    本文实例讲述了JavaScript为事件句柄绑定监听函数的方法.分享给大家供大家参考,具体如下: 在JavaScript中为Dom元素绑定事件监听函数是一件非常常见的事情,但这里也有许多的Bug.各种浏览器对于事件绑定都提供了很多方法,但可靠的只有3中: 1.传统的绑定方法: elem.onclick = function( event ){ alert(event.type + 'this.innerHTML'); }; a.传统的绑定方法,非常简单稳定,函数体内的this指向的也是指向正在处

随机推荐