在一些业务场景中,当容器初始化完成以后,须要处理一些操做,好比一些数据的加载、初始化缓存、特定任务的注册等等。这个时候咱们就可使用Spring提供的ApplicationListener来进行操做。java
本文以在Spring boot下的使用为例来进行说明。首先,须要实现ApplicationListener接口并实现onApplicationEvent方法。把须要处理的操做放在onApplicationEvent中进行处理:spring
package com.secbro.learn.context; import org.springframework.context.ApplicationListener; import org.springframework.context.event.ContextRefreshedEvent; 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; @Configuration public class ListenerConfig { @Bean public ApplicationStartListener applicationStartListener(){ return new ApplicationStartListener(); } }
随后,启动Spring boot服务,打印出一下内容:bash
个人父容器为:null 初始化时我被调用了。
从打印的结果能够看出,ApplicationStartListener的onApplicationEvent方法在容器启动时已经被成功调用了。而此时初始化的容器为root容器。app
此处使用Spring boot来进行操做,没有出现二次调用的问题。在使用传统的application.xml和project-servlet.xml配置中会出现二次调用的问题。主要缘由是初始化root容器以后,会初始化project-servlet.xml对应的子容器。咱们须要的是只执行一遍便可。那么上面打印父容器的代码用来进行判断排除子容器便可。在业务处理以前添加以下判断:ide
if(contextRefreshedEvent.getApplicationContext().getParent() != null){ return; }if(contextRefreshedEvent.getApplicationContext().getParent() != null){ return; }
这样其余容器的初始化就会直接返回,而父容器(Parent为null的容器)启动时将会执行相应的业务操做。spa
在spring中InitializingBean接口也提供了相似的功能,只不过它进行操做的时机是在全部bean都被实例化以后才进行调用。根据不一样的业务场景和需求,可选择不一样的方案来实现。code