• Spring ApplicationListener使用方法及二次调用问题解决


    使用场景

    在一些业务场景中,当容器初始化完成之后,需要处理一些操作,比如一些数据的加载、初始化缓存、特定任务的注册等等。这个时候我们就可以使用Spring提供的ApplicationListener来进行操作。

    用法

    本文以在Spring boot下的使用为例来进行说明。首先,需要实现ApplicationListener接口并实现onApplicationEvent方法。把需要处理的操作放在onApplicationEvent中进行处理:

    package com.secbro.learn.context;
    
    import org.springframework.context.ApplicationListener;
    import org.springframework.context.event.ContextRefreshedEvent;
    
    /**
     * Created by zhuzs on 2017/5/12.
     */
    public class ApplicationStartListener implements ApplicationListener<ContextRefreshedEvent>{
        @Override
        public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) {
            System.out.println("我的父容器为:" + contextRefreshedEvent.getApplicationContext().getParent());
            System.out.println("初始化时我被调用了。");
        }
    }

    然后,实例化ApplicationStartListener这个类,在Spring boot中通过一个配置类来进行实例化:

    package com.secbro.learn.conf;
    
    import com.secbro.learn.context.ApplicationStartListener;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    /**
     * Created by zhuzs on 2017/5/12.
     */
    @Configuration
    public class ListenerConfig {
    
        @Bean
        public ApplicationStartListener applicationStartListener(){
            return new ApplicationStartListener();
        }
    }

    随后,启动Spring boot服务,打印出一下内容:

    我的父容器为:null
    初始化时我被调用了。

    从打印的结果可以看出,ApplicationStartListener的onApplicationEvent方法在容器启动时已经被成功调用了。而此时初始化的容器为root容器。

    二次调用问题

    此处使用Spring boot来进行操作,没有出现二次调用的问题。在使用传统的application.xml和project-servlet.xml配置中会出现二次调用的问题。主要原因是初始化root容器之后,会初始化project-servlet.xml对应的子容器。我们需要的是只执行一遍即可。那么上面打印父容器的代码用来进行判断排除子容器即可。在业务处理之前添加如下判断:

    if(contextRefreshedEvent.getApplicationContext().getParent() != null){
                return;
    }

    这样其他容器的初始化就会直接返回,而父容器(Parent为null的容器)启动时将会执行相应的业务操作。

    关联知识

    在spring中InitializingBean接口也提供了类似的功能,只不过它进行操作的时机是在所有bean都被实例化之后才进行调用。根据不同的业务场景和需求,可选择不同的方案来实现。

    版权声明:本文为博主原创文章,转载请写明出处: https://blog.csdn.net/wo541075754/article/details/71720984
  • 相关阅读:
    require的特点
    require和load的不同之处
    关于“load”方法
    puts方法要点
    用类解释对象的由来
    以方法调用的原理解释Ruby中“puts ‘Hello‘”
    Ruby中方法的设计理念
    Ruby中puts,print,p的区别
    Ubuntu16.04安装MongoDB的Ruby驱动
    使用spring框架,用xml方式进行bean装配出现“The fully qualified name of the bean's class, except if it serves...”
  • 原文地址:https://www.cnblogs.com/cblogs/p/9451053.html
Copyright © 2020-2023  润新知