Commit dcbfb51a authored by Phillip Webb's avatar Phillip Webb

Merge pull request #7336 from mbogoevici/GH-7335-1.4.x

* pr/7336:
  Polish multiple root contexts in `Restarter`
  Support multiple root contexts in `Restarter`
parents 9960e0d6 dfd327d6
...@@ -45,15 +45,14 @@ public class RestartApplicationListener ...@@ -45,15 +45,14 @@ public class RestartApplicationListener
onApplicationStartingEvent((ApplicationStartingEvent) event); onApplicationStartingEvent((ApplicationStartingEvent) event);
} }
if (event instanceof ApplicationPreparedEvent) { if (event instanceof ApplicationPreparedEvent) {
Restarter.getInstance() onApplicationPreparedEvent((ApplicationPreparedEvent) event);
.prepare(((ApplicationPreparedEvent) event).getApplicationContext());
} }
if (event instanceof ApplicationReadyEvent if (event instanceof ApplicationReadyEvent
|| event instanceof ApplicationFailedEvent) { || event instanceof ApplicationFailedEvent) {
Restarter.getInstance().finish(); Restarter.getInstance().finish();
if (event instanceof ApplicationFailedEvent) {
Restarter.getInstance().prepare(null);
} }
if (event instanceof ApplicationFailedEvent) {
onApplicationFailedEvent((ApplicationFailedEvent) event);
} }
} }
...@@ -72,6 +71,14 @@ public class RestartApplicationListener ...@@ -72,6 +71,14 @@ public class RestartApplicationListener
} }
} }
private void onApplicationPreparedEvent(ApplicationPreparedEvent event) {
Restarter.getInstance().prepare(event.getApplicationContext());
}
private void onApplicationFailedEvent(ApplicationFailedEvent event) {
Restarter.getInstance().remove(event.getApplicationContext());
}
@Override @Override
public int getOrder() { public int getOrder() {
return this.order; return this.order;
......
...@@ -31,6 +31,7 @@ import java.util.Map; ...@@ -31,6 +31,7 @@ import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.concurrent.BlockingDeque; import java.util.concurrent.BlockingDeque;
import java.util.concurrent.Callable; import java.util.concurrent.Callable;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.LinkedBlockingDeque; import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadFactory; import java.util.concurrent.ThreadFactory;
import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.Lock;
...@@ -116,7 +117,7 @@ public class Restarter { ...@@ -116,7 +117,7 @@ public class Restarter {
private boolean finished = false; private boolean finished = false;
private volatile ConfigurableApplicationContext rootContext; private final List<ConfigurableApplicationContext> rootContexts = new CopyOnWriteArrayList<ConfigurableApplicationContext>();
/** /**
* Internal constructor to create a new {@link Restarter} instance. * Internal constructor to create a new {@link Restarter} instance.
...@@ -314,9 +315,9 @@ public class Restarter { ...@@ -314,9 +315,9 @@ public class Restarter {
this.logger.debug("Stopping application"); this.logger.debug("Stopping application");
this.stopLock.lock(); this.stopLock.lock();
try { try {
if (this.rootContext != null) { for (ConfigurableApplicationContext context : this.rootContexts) {
this.rootContext.close(); context.close();
this.rootContext = null; this.rootContexts.remove(context);
} }
cleanupCaches(); cleanupCaches();
if (this.forceReferenceCleanup) { if (this.forceReferenceCleanup) {
...@@ -418,7 +419,13 @@ public class Restarter { ...@@ -418,7 +419,13 @@ public class Restarter {
if (applicationContext != null && applicationContext.getParent() != null) { if (applicationContext != null && applicationContext.getParent() != null) {
return; return;
} }
this.rootContext = applicationContext; this.rootContexts.add(applicationContext);
}
void remove(ConfigurableApplicationContext applicationContext) {
if (applicationContext != null) {
this.rootContexts.remove(applicationContext);
}
} }
private LeakSafeThread getLeakSafeThread() { private LeakSafeThread getLeakSafeThread() {
......
...@@ -16,6 +16,8 @@ ...@@ -16,6 +16,8 @@
package org.springframework.boot.devtools.restart; package org.springframework.boot.devtools.restart;
import java.util.List;
import org.junit.After; import org.junit.After;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
...@@ -64,8 +66,8 @@ public class RestartApplicationListenerTests { ...@@ -64,8 +66,8 @@ public class RestartApplicationListenerTests {
assertThat(ReflectionTestUtils.getField(Restarter.getInstance(), "args")) assertThat(ReflectionTestUtils.getField(Restarter.getInstance(), "args"))
.isEqualTo(ARGS); .isEqualTo(ARGS);
assertThat(Restarter.getInstance().isFinished()).isTrue(); assertThat(Restarter.getInstance().isFinished()).isTrue();
assertThat(ReflectionTestUtils.getField(Restarter.getInstance(), "rootContext")) assertThat((List<?>) ReflectionTestUtils.getField(Restarter.getInstance(),
.isNotNull(); "rootContexts")).isNotEmpty();
} }
@Test @Test
...@@ -74,8 +76,8 @@ public class RestartApplicationListenerTests { ...@@ -74,8 +76,8 @@ public class RestartApplicationListenerTests {
assertThat(ReflectionTestUtils.getField(Restarter.getInstance(), "args")) assertThat(ReflectionTestUtils.getField(Restarter.getInstance(), "args"))
.isEqualTo(ARGS); .isEqualTo(ARGS);
assertThat(Restarter.getInstance().isFinished()).isTrue(); assertThat(Restarter.getInstance().isFinished()).isTrue();
assertThat(ReflectionTestUtils.getField(Restarter.getInstance(), "rootContext")) assertThat((List<?>) ReflectionTestUtils.getField(Restarter.getInstance(),
.isNull(); "rootContexts")).isEmpty();
} }
@Test @Test
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment