mirror of
https://github.com/spring-projects/spring-boot.git
synced 2024-09-03 04:26:12 +08:00
Merge branch '3.1.x'
This commit is contained in:
commit
fb4b26a842
@ -30,6 +30,7 @@ import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
@ -1457,10 +1458,10 @@ public class SpringApplication {
|
||||
*/
|
||||
public SpringApplication.Running run(String... args) {
|
||||
RunListener runListener = new RunListener();
|
||||
SpringApplicationHook hook = (springApplication) -> {
|
||||
SpringApplicationHook hook = new SingleUseSpringApplicationHook((springApplication) -> {
|
||||
springApplication.addPrimarySources(this.sources);
|
||||
return runListener;
|
||||
};
|
||||
});
|
||||
withHook(hook, () -> this.main.accept(args));
|
||||
return runListener;
|
||||
}
|
||||
@ -1580,4 +1581,21 @@ public class SpringApplication {
|
||||
|
||||
}
|
||||
|
||||
private static final class SingleUseSpringApplicationHook implements SpringApplicationHook {
|
||||
|
||||
private final AtomicBoolean used = new AtomicBoolean();
|
||||
|
||||
private final SpringApplicationHook delegate;
|
||||
|
||||
private SingleUseSpringApplicationHook(SpringApplicationHook delegate) {
|
||||
this.delegate = delegate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SpringApplicationRunListener getRunListener(SpringApplication springApplication) {
|
||||
return this.used.compareAndSet(false, true) ? this.delegate.getRunListener(springApplication) : null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -24,6 +24,7 @@ import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.function.Supplier;
|
||||
@ -1363,18 +1364,30 @@ class SpringApplicationTests {
|
||||
@Test
|
||||
void fromRunsWithAdditionalSources() {
|
||||
assertThat(ExampleAdditionalConfig.local.get()).isNull();
|
||||
SpringApplication.from(ExampleFromMainMethod::main).with(ExampleAdditionalConfig.class).run();
|
||||
this.context = SpringApplication.from(ExampleFromMainMethod::main)
|
||||
.with(ExampleAdditionalConfig.class)
|
||||
.run()
|
||||
.getApplicationContext();
|
||||
assertThat(ExampleAdditionalConfig.local.get()).isNotNull();
|
||||
ExampleAdditionalConfig.local.set(null);
|
||||
}
|
||||
|
||||
@Test
|
||||
void fromReturnsApplicationContext() {
|
||||
ConfigurableApplicationContext context = SpringApplication.from(ExampleFromMainMethod::main)
|
||||
this.context = SpringApplication.from(ExampleFromMainMethod::main)
|
||||
.with(ExampleAdditionalConfig.class)
|
||||
.run()
|
||||
.getApplicationContext();
|
||||
assertThat(context).isNotNull();
|
||||
assertThat(this.context).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void fromWithMultipleApplicationsOnlyAppliesAdditionalSourcesOnce() {
|
||||
this.context = SpringApplication.from(MultipleApplicationsMainMethod::main)
|
||||
.with(SingleUseAdditionalConfig.class)
|
||||
.run()
|
||||
.getApplicationContext();
|
||||
assertThatNoException().isThrownBy(() -> this.context.getBean(SingleUseAdditionalConfig.class));
|
||||
}
|
||||
|
||||
private <S extends AvailabilityState> ArgumentMatcher<ApplicationEvent> isAvailabilityChangeEventWithState(
|
||||
@ -1949,6 +1962,31 @@ class SpringApplicationTests {
|
||||
|
||||
}
|
||||
|
||||
static class MultipleApplicationsMainMethod {
|
||||
|
||||
static void main(String[] args) {
|
||||
SpringApplication application = new SpringApplication(ExampleConfig.class);
|
||||
application.setWebApplicationType(WebApplicationType.NONE);
|
||||
application.addListeners(new ApplicationListener<ApplicationEnvironmentPreparedEvent>() {
|
||||
|
||||
@Override
|
||||
public void onApplicationEvent(ApplicationEnvironmentPreparedEvent event) {
|
||||
SpringApplicationBuilder builder = new SpringApplicationBuilder(
|
||||
InnerApplicationConfiguration.class);
|
||||
builder.web(WebApplicationType.NONE);
|
||||
builder.run().close();
|
||||
}
|
||||
|
||||
});
|
||||
application.run(args);
|
||||
}
|
||||
|
||||
static class InnerApplicationConfiguration {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
static class ExampleAdditionalConfig {
|
||||
|
||||
@ -1960,4 +1998,17 @@ class SpringApplicationTests {
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
static class SingleUseAdditionalConfig {
|
||||
|
||||
private static AtomicBoolean used = new AtomicBoolean(false);
|
||||
|
||||
SingleUseAdditionalConfig() {
|
||||
if (!used.compareAndSet(false, true)) {
|
||||
throw new IllegalStateException("Single-use configuration has already been used");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user