Optionally close context after command logic
- spring.shell.context.close=true adds ApplicationListerner which attempts to close context with ApplicationReadyEvent. - Relates #863
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2021 the original author or authors.
|
||||
* Copyright 2021-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -19,7 +19,10 @@ import java.util.List;
|
||||
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.boot.context.event.ApplicationReadyEvent;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.shell.DefaultShellApplicationRunner;
|
||||
import org.springframework.shell.ShellApplicationRunner;
|
||||
@@ -34,4 +37,20 @@ public class ApplicationRunnerAutoConfiguration {
|
||||
public DefaultShellApplicationRunner defaultShellApplicationRunner(List<ShellRunner> shellRunners) {
|
||||
return new DefaultShellApplicationRunner(shellRunners);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnProperty(prefix = "spring.shell.context", name = "close", havingValue = "true")
|
||||
public ApplicationReadyEventListener applicationReadyEventListener() {
|
||||
return new ApplicationReadyEventListener();
|
||||
}
|
||||
|
||||
static class ApplicationReadyEventListener implements ApplicationListener<ApplicationReadyEvent>{
|
||||
|
||||
@Override
|
||||
public void onApplicationEvent(ApplicationReadyEvent event) {
|
||||
// request context close after application runners so that
|
||||
// shell exits in case that context is kept alive
|
||||
event.getApplicationContext().close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@ public class SpringShellProperties {
|
||||
private Command command = new Command();
|
||||
private Help help = new Help();
|
||||
private Option option = new Option();
|
||||
private Context context = new Context();
|
||||
|
||||
public void setConfig(Config config) {
|
||||
this.config = config;
|
||||
@@ -107,6 +108,14 @@ public class SpringShellProperties {
|
||||
this.option = option;
|
||||
}
|
||||
|
||||
public Context getContext() {
|
||||
return context;
|
||||
}
|
||||
|
||||
public void setContext(Context context) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
public static class Config {
|
||||
|
||||
private String env;
|
||||
@@ -603,6 +612,19 @@ public class SpringShellProperties {
|
||||
}
|
||||
}
|
||||
|
||||
public static class Context {
|
||||
|
||||
private boolean close = false;
|
||||
|
||||
public boolean isClose() {
|
||||
return close;
|
||||
}
|
||||
|
||||
public void setClose(boolean close) {
|
||||
this.close = close;
|
||||
}
|
||||
}
|
||||
|
||||
public static enum OptionNamingCase {
|
||||
NOOP,
|
||||
CAMEL,
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright 2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.shell.boot;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
public class ApplicationRunnerAutoConfigurationTests {
|
||||
|
||||
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
|
||||
.withConfiguration(AutoConfigurations.of(ApplicationRunnerAutoConfiguration.class));
|
||||
|
||||
@Test
|
||||
void contextCloseDisabledByDefault() {
|
||||
contextRunner.run(context -> assertThat(context)
|
||||
.doesNotHaveBean(ApplicationRunnerAutoConfiguration.ApplicationReadyEventListener.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void contextCloseEnabled() {
|
||||
contextRunner.withPropertyValues("spring.shell.context.close:true")
|
||||
.run(context -> assertThat(context)
|
||||
.hasSingleBean(ApplicationRunnerAutoConfiguration.ApplicationReadyEventListener.class));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -70,6 +70,7 @@ public class SpringShellPropertiesTests {
|
||||
assertThat(properties.getHelp().getLongNames()).containsExactly("help");
|
||||
assertThat(properties.getHelp().getShortNames()).containsExactly('h');
|
||||
assertThat(properties.getOption().getNaming().getCaseType()).isEqualTo(OptionNamingCase.NOOP);
|
||||
assertThat(properties.getContext().isClose()).isFalse();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -112,6 +113,7 @@ public class SpringShellPropertiesTests {
|
||||
.withPropertyValues("spring.shell.help.long-names=fake")
|
||||
.withPropertyValues("spring.shell.help.short-names=f")
|
||||
.withPropertyValues("spring.shell.option.naming.case-type=camel")
|
||||
.withPropertyValues("spring.shell.context.close=true")
|
||||
.withUserConfiguration(Config1.class)
|
||||
.run((context) -> {
|
||||
SpringShellProperties properties = context.getBean(SpringShellProperties.class);
|
||||
@@ -151,6 +153,7 @@ public class SpringShellPropertiesTests {
|
||||
assertThat(properties.getHelp().getLongNames()).containsExactly("fake");
|
||||
assertThat(properties.getHelp().getShortNames()).containsExactly('f');
|
||||
assertThat(properties.getOption().getNaming().getCaseType()).isEqualTo(OptionNamingCase.CAMEL);
|
||||
assertThat(properties.getContext().isClose()).isTrue();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user