001/* 002 * Copyright 2012-2018 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.springframework.boot.builder; 018 019import org.springframework.context.ApplicationContext; 020import org.springframework.context.ApplicationContextInitializer; 021import org.springframework.context.ApplicationEvent; 022import org.springframework.context.ApplicationListener; 023import org.springframework.context.ConfigurableApplicationContext; 024import org.springframework.context.event.ContextRefreshedEvent; 025import org.springframework.core.Ordered; 026 027/** 028 * {@link ApplicationContextInitializer} for setting the parent context. Also publishes 029 * {@link ParentContextAvailableEvent} when the context is refreshed to signal to other 030 * listeners that the context is available and has a parent. 031 * 032 * @author Dave Syer 033 */ 034public class ParentContextApplicationContextInitializer implements 035 ApplicationContextInitializer<ConfigurableApplicationContext>, Ordered { 036 037 private int order = Ordered.HIGHEST_PRECEDENCE; 038 039 private final ApplicationContext parent; 040 041 public ParentContextApplicationContextInitializer(ApplicationContext parent) { 042 this.parent = parent; 043 } 044 045 public void setOrder(int order) { 046 this.order = order; 047 } 048 049 @Override 050 public int getOrder() { 051 return this.order; 052 } 053 054 @Override 055 public void initialize(ConfigurableApplicationContext applicationContext) { 056 if (applicationContext != this.parent) { 057 applicationContext.setParent(this.parent); 058 applicationContext.addApplicationListener(EventPublisher.INSTANCE); 059 } 060 } 061 062 private static class EventPublisher 063 implements ApplicationListener<ContextRefreshedEvent>, Ordered { 064 065 private static final EventPublisher INSTANCE = new EventPublisher(); 066 067 @Override 068 public int getOrder() { 069 return Ordered.HIGHEST_PRECEDENCE; 070 } 071 072 @Override 073 public void onApplicationEvent(ContextRefreshedEvent event) { 074 ApplicationContext context = event.getApplicationContext(); 075 if (context instanceof ConfigurableApplicationContext 076 && context == event.getSource()) { 077 context.publishEvent(new ParentContextAvailableEvent( 078 (ConfigurableApplicationContext) context)); 079 } 080 } 081 082 } 083 084 /** 085 * {@link ApplicationEvent} fired when a parent context is available. 086 */ 087 @SuppressWarnings("serial") 088 public static class ParentContextAvailableEvent extends ApplicationEvent { 089 090 public ParentContextAvailableEvent( 091 ConfigurableApplicationContext applicationContext) { 092 super(applicationContext); 093 } 094 095 public ConfigurableApplicationContext getApplicationContext() { 096 return (ConfigurableApplicationContext) getSource(); 097 } 098 099 } 100 101}