开源项目halo个人博客源码学习--halo的事件监听机制(四)

halo的事件监听机制

一、概述

让我们来看看event和listener的包结构
在这里插入图片描述在这里插入图片描述

首先,我们要对springboot的事件监听机制要有一定了解。listener也就是监听器,对应监听着一个事件,当这个事件被发布后,listener做出对应的反应,比如说记录日志就用到了一些事件监听方面的知识。

对于springboot来说,如果我们我想发布事件,我们只需要调用AppilicationContext的publishEvent()方法,方法的参数必须是ApplicationEvent,所以我们得让我们的事件继承ApplicationEvent。打开各个事件的类,果不其然,最后都继承了ApplicationEvent。

同理,如果我们想监听springboot中发生的事件,我们需要自定义listener实现ApplicationListener<>接口,泛型需要传入我们要监听的事件。或者说使用spring为我们提供的**@EventListener标注在我们监听的方法上。并使用@Conponent**将这个监听类加载到容器中。

二、举例说明

下面,我们以StartedListener监听器为例,

public class StartedListener implements ApplicationListener<ApplicationStartedEvent>{
    ...
}

ApplicationStartedEvent是StartedListener 监听的事件,ApplicationStartedEvent是个什么东西呢,我们点开它。

public class ApplicationStartedEvent extends SpringApplicationEvent {
    ...
}

SpringApplicationEvent是springboot给我们定义的事件,它也继承的ApplicationEvent,我们来看看他们之间的继承关系就清楚了。
在这里插入图片描述

对springboot启动流程熟悉同学们都知道,在springboot启动完成后,SpringApplicationRunListener调用started()方法

public ConfigurableApplicationContext run(String... args) {
		StopWatch stopWatch = new StopWatch();
		stopWatch.start();
		ConfigurableApplicationContext context = null;
		Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();
		configureHeadlessProperty();
		SpringApplicationRunListeners listeners = getRunListeners(args);
		listeners.starting();
		try {
			ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
			ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);
			configureIgnoreBeanInfo(environment);
			Banner printedBanner = printBanner(environment);
			context = createApplicationContext();
			exceptionReporters = getSpringFactoriesInstances(SpringBootExceptionReporter.class,
					new Class[] { ConfigurableApplicationContext.class }, context);
			prepareContext(context, environment, listeners, applicationArguments, printedBanner);
			refreshContext(context);
			afterRefresh(context, applicationArguments);
			stopWatch.stop();
			if (this.logStartupInfo) {
				new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), stopWatch);
			}
            //容器创建完成,调用started方法
			listeners.started(context);
			callRunners(context, applicationArguments);
		}
		catch (Throwable ex) {
			handleRunFailure(context, ex, exceptionReporters, listeners);
			throw new IllegalStateException(ex);
		}

		try {
			listeners.running(context);
		}
		catch (Throwable ex) {
			handleRunFailure(context, ex, exceptionReporters, null);
			throw new IllegalStateException(ex);
		}
		return context;
	}

进入started方法,遍历所有的SpringApplicationRunListener调用started方法。started方法使用context发布了ApplicationStartedEvent事件。

@Override
	public void started(ConfigurableApplicationContext context) {
		context.publishEvent(new ApplicationStartedEvent(this.application, this.args, context));
		AvailabilityChangeEvent.publish(context, LivenessState.CORRECT);
	}

也就是说,只要我们监听这个事件,当事件完成(springboot启动成功后)我们就能onApplicationEvent()方法中自定义操作,比如说打印定制信息。

@Override
    public void onApplicationEvent(ApplicationStartedEvent event) {
        try {
            //创建数据库
            this.migrate();
        } catch (SQLException e) {
            log.error("Failed to migrate database!", e);
        }
        //初始化主题
        this.initThemes();
        //初始化文件夹
        this.initDirectory();
        //控制台打印信息
        this.printStartInfo();
    }

三、总结

当我们自己在写业务代码时,我们可以自定义一些事件,自定义一些监听器,让我们更好的监控我们整个应用程序的运行情况。事件监听同时也对应了设计模式中的观察者模式。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值