• spring boot实战(第二篇)事件监听


    http://blog.csdn.net/liaokailin/article/details/48186331

    前言

    spring boot在启动过程中增加事件监听机制,为用户功能拓展提供极大的便利。

    支持的事件类型四种

    ApplicationStartedEvent

    ApplicationEnvironmentPreparedEvent

    ApplicationPreparedEvent

    ApplicationFailedEvent

    实现监听步骤:

    1.监听类实现ApplicationListener接口 
    2.将监听类添加到SpringApplication实例

    ApplicationStartedEvent

    ApplicationStartedEvent:spring boot启动开始时执行的事件

    创建对应的监听类 MyApplicationStartedEventListener.java

    package com.lkl.springboot.listener;
    
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.context.event.ApplicationStartedEvent;
    import org.springframework.context.ApplicationListener;
    
    /**
     * spring boot 启动监听类
     * 
     * @author liaokailin
     * @version $Id: MyApplicationStartedEventListener.java, v 0.1 2015年9月2日 下午11:06:04 liaokailin Exp $
     */
    public class MyApplicationStartedEventListener implements ApplicationListener<ApplicationStartedEvent> {
    
        private Logger logger = LoggerFactory.getLogger(MyApplicationStartedEventListener.class);
    
        @Override
        public void onApplicationEvent(ApplicationStartedEvent event) {
            SpringApplication app = event.getSpringApplication();
            app.setShowBanner(false);// 不显示banner信息
            logger.info("==MyApplicationStartedEventListener==");
        }
    }

    在该事件中可以获取到SpringApplication对象,可做一些执行前的设置.

    Application.java

    package com.lkl.springboot;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    
    import com.lkl.springboot.listener.MyApplicationStartedEventListener;
    
    @SpringBootApplication
    public class Application {
        public static void main(String[] args) {
            SpringApplication app = new SpringApplication(Application.class); 
            app.addListeners(new MyApplicationStartedEventListener());
            app.run(args);
        }
    }

    ApplicationEnvironmentPreparedEvent

    ApplicationEnvironmentPreparedEvent:spring boot 对应Enviroment已经准备完毕,但此时上下文context还没有创建。

    MyApplicationEnvironmentPreparedEventListener.java

    package com.lkl.springboot.listener;
    
    import java.util.Iterator;
    
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.boot.context.event.ApplicationEnvironmentPreparedEvent;
    import org.springframework.context.ApplicationListener;
    import org.springframework.core.env.ConfigurableEnvironment;
    import org.springframework.core.env.MutablePropertySources;
    import org.springframework.core.env.PropertySource;
    
    /**
     * spring boot 配置环境事件监听
     * @author liaokailin
     * @version $Id: MyApplicationEnvironmentPreparedEventListener.java, v 0.1 2015年9月2日 下午11:21:15 liaokailin Exp $
     */
    public class MyApplicationEnvironmentPreparedEventListener implements
                                                              ApplicationListener<ApplicationEnvironmentPreparedEvent> {
        private Logger logger = LoggerFactory.getLogger(MyApplicationEnvironmentPreparedEventListener.class);
    
        @Override
        public void onApplicationEvent(ApplicationEnvironmentPreparedEvent event) {
    
            ConfigurableEnvironment envi = event.getEnvironment();
            MutablePropertySources mps = envi.getPropertySources();
            if (mps != null) {
                Iterator<PropertySource<?>> iter = mps.iterator();
                while (iter.hasNext()) {
                    PropertySource<?> ps = iter.next();
                    logger
                        .info("ps.getName:{};ps.getSource:{};ps.getClass:{}", ps.getName(), ps.getSource(), ps.getClass());
                }
            }
        }
    
    }
    

    在该监听中获取到ConfigurableEnvironment后可以对配置信息做操作,例如:修改默认的配置信息,增加额外的配置信息等等~~~

    ApplicationPreparedEvent

    ApplicationPreparedEvent:spring boot上下文context创建完成,但此时spring中的bean是没有完全加载完成的。

    MyApplicationPreparedEventListener.java

    package com.lkl.springboot.listener;
    
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.boot.context.event.ApplicationPreparedEvent;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.ApplicationListener;
    import org.springframework.context.ConfigurableApplicationContext;
    
    /**
     * 上下文创建完成后执行的事件监听器
     * 
     * @author liaokailin
     * @version $Id: MyApplicationPreparedEventListener.java, v 0.1 2015年9月2日 下午11:29:38 liaokailin Exp $
     */
    public class MyApplicationPreparedEventListener implements ApplicationListener<ApplicationPreparedEvent> {
        private Logger logger = LoggerFactory.getLogger(MyApplicationPreparedEventListener.class);
    
        @Override
        public void onApplicationEvent(ApplicationPreparedEvent event) {
            ConfigurableApplicationContext cac = event.getApplicationContext();
            passContextInfo(cac);
        }
    
        /**
         * 传递上下文
         * @param cac
         */
        private void passContextInfo(ApplicationContext cac) {
            //dosomething()
        }
    
    }

    在获取完上下文后,可以将上下文传递出去做一些额外的操作。

    在该监听器中是无法获取自定义bean并进行操作的。

    ApplicationFailedEvent

    ApplicationFailedEvent:spring boot启动异常时执行事件 
    MyApplicationFailedEventListener.java

    package com.lkl.springboot.listener;
    
    import org.springframework.boot.context.event.ApplicationFailedEvent;
    import org.springframework.context.ApplicationListener;
    
    public class MyApplicationFailedEventListener implements ApplicationListener<ApplicationFailedEvent> {
    
        @Override
        public void onApplicationEvent(ApplicationFailedEvent event) {
            Throwable throwable = event.getException();
            handleThrowable(throwable);
        }
    
        /*处理异常*/
        private void handleThrowable(Throwable throwable) {
        }
    
    }

    在异常发生时,最好是添加虚拟机对应的钩子进行资源的回收与释放,能友善的处理异常信息。

    在spring boot中已经为大家考虑了这一点,默认情况开启了对应的功能:

    public void registerShutdownHook() {
            if (this.shutdownHook == null) {
                // No shutdown hook registered yet.
                this.shutdownHook = new Thread() {
                    @Override
                    public void run() {
                        doClose();
                    }
                };
                Runtime.getRuntime().addShutdownHook(this.shutdownHook);
            }
        }

    doClose()方法中进行资源的回收与释放。

    结束语

    spring boot提供的四种监听事件到这里就结束了,针对实际业务可添加自定义的监听器,下一节当中将会对spring boot中的监听源码进行分析,理解为什么是这样的。

  • 相关阅读:
    用两个栈实现队列
    *重建二叉树
    *链表中环的入口结点
    *复杂链表的复制
    替换空格
    python多线程文件拷贝
    进程、线程、协程
    文件处理工具sed、awk
    CentOs软件安装
    python logging模块
  • 原文地址:https://www.cnblogs.com/exmyth/p/7750770.html
Copyright © 2020-2023  润新知