mirror of
https://github.com/spring-projects/spring-boot.git
synced 2024-09-03 04:26:12 +08:00
Merge branch '3.1.x'
Closes gh-37921
This commit is contained in:
commit
9460f301b4
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2012-2022 the original author or authors.
|
* Copyright 2012-2023 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@ -23,6 +23,7 @@ import org.springframework.boot.context.event.ApplicationFailedEvent;
|
|||||||
import org.springframework.boot.context.event.ApplicationPreparedEvent;
|
import org.springframework.boot.context.event.ApplicationPreparedEvent;
|
||||||
import org.springframework.boot.context.event.ApplicationReadyEvent;
|
import org.springframework.boot.context.event.ApplicationReadyEvent;
|
||||||
import org.springframework.boot.context.event.ApplicationStartingEvent;
|
import org.springframework.boot.context.event.ApplicationStartingEvent;
|
||||||
|
import org.springframework.boot.devtools.system.DevToolsEnablementDeducer;
|
||||||
import org.springframework.context.ApplicationEvent;
|
import org.springframework.context.ApplicationEvent;
|
||||||
import org.springframework.context.ApplicationListener;
|
import org.springframework.context.ApplicationListener;
|
||||||
import org.springframework.core.Ordered;
|
import org.springframework.core.Ordered;
|
||||||
@ -66,8 +67,15 @@ public class RestartApplicationListener implements ApplicationListener<Applicati
|
|||||||
String enabled = System.getProperty(ENABLED_PROPERTY);
|
String enabled = System.getProperty(ENABLED_PROPERTY);
|
||||||
RestartInitializer restartInitializer = null;
|
RestartInitializer restartInitializer = null;
|
||||||
if (enabled == null) {
|
if (enabled == null) {
|
||||||
|
if (implicitlyEnableRestart()) {
|
||||||
restartInitializer = new DefaultRestartInitializer();
|
restartInitializer = new DefaultRestartInitializer();
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
logger.info("Restart disabled due to context in which it is running");
|
||||||
|
Restarter.disable();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
else if (Boolean.parseBoolean(enabled)) {
|
else if (Boolean.parseBoolean(enabled)) {
|
||||||
restartInitializer = new DefaultRestartInitializer() {
|
restartInitializer = new DefaultRestartInitializer() {
|
||||||
|
|
||||||
@ -96,6 +104,10 @@ public class RestartApplicationListener implements ApplicationListener<Applicati
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean implicitlyEnableRestart() {
|
||||||
|
return DevToolsEnablementDeducer.shouldEnable(Thread.currentThread());
|
||||||
|
}
|
||||||
|
|
||||||
private void onApplicationPreparedEvent(ApplicationPreparedEvent event) {
|
private void onApplicationPreparedEvent(ApplicationPreparedEvent event) {
|
||||||
Restarter.getInstance().prepare(event.getApplicationContext());
|
Restarter.getInstance().prepare(event.getApplicationContext());
|
||||||
}
|
}
|
||||||
|
@ -408,7 +408,7 @@ public class Restarter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void prepare(ConfigurableApplicationContext applicationContext) {
|
void prepare(ConfigurableApplicationContext applicationContext) {
|
||||||
if (applicationContext != null && applicationContext.getParent() != null) {
|
if (!this.enabled || (applicationContext != null && applicationContext.getParent() != null)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (applicationContext instanceof GenericApplicationContext genericContext) {
|
if (applicationContext instanceof GenericApplicationContext genericContext) {
|
||||||
|
@ -65,7 +65,7 @@ class RestartApplicationListenerTests {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
void initializeWithReady() {
|
void initializeWithReady() {
|
||||||
testInitialize(false);
|
testInitialize(false, new ImplicitlyEnabledRestartApplicationListener());
|
||||||
assertThat(Restarter.getInstance()).hasFieldOrPropertyWithValue("args", ARGS);
|
assertThat(Restarter.getInstance()).hasFieldOrPropertyWithValue("args", ARGS);
|
||||||
assertThat(Restarter.getInstance().isFinished()).isTrue();
|
assertThat(Restarter.getInstance().isFinished()).isTrue();
|
||||||
assertThat((List<?>) ReflectionTestUtils.getField(Restarter.getInstance(), "rootContexts")).isNotEmpty();
|
assertThat((List<?>) ReflectionTestUtils.getField(Restarter.getInstance(), "rootContexts")).isNotEmpty();
|
||||||
@ -73,7 +73,7 @@ class RestartApplicationListenerTests {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
void initializeWithFail() {
|
void initializeWithFail() {
|
||||||
testInitialize(true);
|
testInitialize(true, new ImplicitlyEnabledRestartApplicationListener());
|
||||||
assertThat(Restarter.getInstance()).hasFieldOrPropertyWithValue("args", ARGS);
|
assertThat(Restarter.getInstance()).hasFieldOrPropertyWithValue("args", ARGS);
|
||||||
assertThat(Restarter.getInstance().isFinished()).isTrue();
|
assertThat(Restarter.getInstance().isFinished()).isTrue();
|
||||||
assertThat((List<?>) ReflectionTestUtils.getField(Restarter.getInstance(), "rootContexts")).isEmpty();
|
assertThat((List<?>) ReflectionTestUtils.getField(Restarter.getInstance(), "rootContexts")).isEmpty();
|
||||||
@ -82,7 +82,7 @@ class RestartApplicationListenerTests {
|
|||||||
@Test
|
@Test
|
||||||
void disableWithSystemProperty(CapturedOutput output) {
|
void disableWithSystemProperty(CapturedOutput output) {
|
||||||
System.setProperty(ENABLED_PROPERTY, "false");
|
System.setProperty(ENABLED_PROPERTY, "false");
|
||||||
testInitialize(false);
|
testInitialize(false, new ImplicitlyEnabledRestartApplicationListener());
|
||||||
assertThat(Restarter.getInstance()).hasFieldOrPropertyWithValue("enabled", false);
|
assertThat(Restarter.getInstance()).hasFieldOrPropertyWithValue("enabled", false);
|
||||||
assertThat(output).contains("Restart disabled due to System property");
|
assertThat(output).contains("Restart disabled due to System property");
|
||||||
}
|
}
|
||||||
@ -90,14 +90,28 @@ class RestartApplicationListenerTests {
|
|||||||
@Test
|
@Test
|
||||||
void enableWithSystemProperty(CapturedOutput output) {
|
void enableWithSystemProperty(CapturedOutput output) {
|
||||||
System.setProperty(ENABLED_PROPERTY, "true");
|
System.setProperty(ENABLED_PROPERTY, "true");
|
||||||
testInitialize(false);
|
testInitialize(false, new ImplicitlyEnabledRestartApplicationListener());
|
||||||
assertThat(Restarter.getInstance()).hasFieldOrPropertyWithValue("enabled", true);
|
assertThat(Restarter.getInstance()).hasFieldOrPropertyWithValue("enabled", true);
|
||||||
assertThat(output).contains("Restart enabled irrespective of application packaging due to System property");
|
assertThat(output).contains("Restart enabled irrespective of application packaging due to System property");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void testInitialize(boolean failed) {
|
@Test
|
||||||
|
void enableWithSystemPropertyWhenImplicitlyDisabled(CapturedOutput output) {
|
||||||
|
System.setProperty(ENABLED_PROPERTY, "true");
|
||||||
|
testInitialize(false, new RestartApplicationListener());
|
||||||
|
assertThat(Restarter.getInstance()).hasFieldOrPropertyWithValue("enabled", true);
|
||||||
|
assertThat(output).contains("Restart enabled irrespective of application packaging due to System property");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void implicitlyDisabledInTests(CapturedOutput output) {
|
||||||
|
testInitialize(false, new RestartApplicationListener());
|
||||||
|
assertThat(Restarter.getInstance()).hasFieldOrPropertyWithValue("enabled", false);
|
||||||
|
assertThat(output).contains("Restart disabled due to context in which it is running");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void testInitialize(boolean failed, RestartApplicationListener listener) {
|
||||||
Restarter.clearInstance();
|
Restarter.clearInstance();
|
||||||
RestartApplicationListener listener = new RestartApplicationListener();
|
|
||||||
DefaultBootstrapContext bootstrapContext = new DefaultBootstrapContext();
|
DefaultBootstrapContext bootstrapContext = new DefaultBootstrapContext();
|
||||||
SpringApplication application = new SpringApplication();
|
SpringApplication application = new SpringApplication();
|
||||||
ConfigurableApplicationContext context = mock(ConfigurableApplicationContext.class);
|
ConfigurableApplicationContext context = mock(ConfigurableApplicationContext.class);
|
||||||
@ -113,4 +127,13 @@ class RestartApplicationListenerTests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static class ImplicitlyEnabledRestartApplicationListener extends RestartApplicationListener {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
boolean implicitlyEnableRestart() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,7 @@ import java.util.Collections;
|
|||||||
import java.util.concurrent.ThreadFactory;
|
import java.util.concurrent.ThreadFactory;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
|
import org.assertj.core.api.InstanceOfAssertFactories;
|
||||||
import org.awaitility.Awaitility;
|
import org.awaitility.Awaitility;
|
||||||
import org.junit.jupiter.api.AfterEach;
|
import org.junit.jupiter.api.AfterEach;
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
@ -37,6 +38,7 @@ import org.springframework.boot.devtools.restart.classloader.ClassLoaderFiles;
|
|||||||
import org.springframework.boot.test.system.CapturedOutput;
|
import org.springframework.boot.test.system.CapturedOutput;
|
||||||
import org.springframework.boot.test.system.OutputCaptureExtension;
|
import org.springframework.boot.test.system.OutputCaptureExtension;
|
||||||
import org.springframework.context.ApplicationListener;
|
import org.springframework.context.ApplicationListener;
|
||||||
|
import org.springframework.context.ConfigurableApplicationContext;
|
||||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||||
import org.springframework.context.event.ContextClosedEvent;
|
import org.springframework.context.event.ContextClosedEvent;
|
||||||
import org.springframework.scheduling.annotation.EnableScheduling;
|
import org.springframework.scheduling.annotation.EnableScheduling;
|
||||||
@ -44,6 +46,7 @@ import org.springframework.scheduling.annotation.Scheduled;
|
|||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.as;
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
|
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
|
||||||
import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
|
import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
|
||||||
@ -90,6 +93,14 @@ class RestarterTests {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testDisabled() {
|
||||||
|
Restarter.disable();
|
||||||
|
ConfigurableApplicationContext context = mock(ConfigurableApplicationContext.class);
|
||||||
|
Restarter.getInstance().prepare(context);
|
||||||
|
assertThat(Restarter.getInstance()).extracting("rootContexts", as(InstanceOfAssertFactories.LIST)).isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@SuppressWarnings("rawtypes")
|
@SuppressWarnings("rawtypes")
|
||||||
void getOrAddAttributeWithNewAttribute() {
|
void getOrAddAttributeWithNewAttribute() {
|
||||||
|
Loading…
Reference in New Issue
Block a user