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事件源 } }