import org.springframework.context.ApplicationListener; import org.springframework.context.event.ContextRefreshedEvent; import org.springframework.stereotype.Service; @Slf4j @Service public class ParamsContextAdapter implements ApplicationListener<ContextRefreshedEvent> { @Override public void onApplicationEvent(ContextRefreshedEvent event) { try { // 生成了两个AnnotationConfigApplicationContext子容器; //父容器为AnnotationConfigEmbeddedWebApplicationContext; //祖父容器为AnnotationConfigApplicationContext ApplicationContext child = event.getApplicationContext(); ApplicationContext parent = event.getApplicationContext().getParent(); ApplicationContext grandParent = parent != null ? parent.getParent() : null; log.info("当前:{}; 父亲:{}; 祖父:{}", child.getDisplayName(), parent == null ? null : parent.getDisplayName(), grandParent == null ? null : grandParent.getDisplayName()); if (event.getApplicationContext().getParent().getParent() == null) { log.info("初始化适配器开始"); System.out.println("test ApplicationListener"); log.info("初始化适配器完成"); } } catch (Exception e) { log.error("初始化适配器异常", e); } } }
同时集成了spring和springMVC的话,上下文中会存在父、子容器,(spring配置文件的<context-param>contextConfigLocation的父容器和springMVC配置文件的<init-param>contextConfigLocation的子容器), 在经过applicationContext发送通知的时候,事件可能会被两个容器同时发布。能够先排除是否因为配置有误形成。再给定执行前的断定java
@Override public void onApplicationEvent(ContextRefreshedEvent event) { if(event.getApplicationContext().getParent() == null){ //须要执行的逻辑代码,当spring容器初始化完成后就会执行该方法。 } }
在AbstractApplicationContext.refresh(); 对容器加载编排的过程当中,若是父容器不为空,父容器也publish事件源,因此生成了几回容器也对执行有影响spring
AbstractApplicationContext: protected void finishRefresh() { // Initialize lifecycle processor for this context. initLifecycleProcessor(); // Propagate refresh to lifecycle processor first. getLifecycleProcessor().onRefresh(); // Publish the final event. 将上下文ApplicationContext注入到ContextRefreshedEvent中 publishEvent(new ContextRefreshedEvent(this)); } public void publishEvent(ApplicationEvent event) { Assert.notNull(event, "Event must not be null"); if (logger.isTraceEnabled()) { logger.trace("Publishing event in " + getDisplayName() + ": " + event); } getApplicationEventMulticaster().multicastEvent(event); if (this.parent != null) { this.parent.publishEvent(event); // 若是父容器不为空,父容器也publish事件源 } }