Skip to content

Commit 2b6298e

Browse files
committed
GH-145 - Make sure the async ApplicationModulesRuntime bootstrap doesn't prevent shutdown.
We now use an AsyncTaskExecutor to bootstrap the ApplicationModules instance at startup asynchronously and - at the same time - do not block an explicit application shutdown. This also more idiomatic compared to using an ExecutorService directly.
1 parent 815df25 commit 2b6298e

File tree

3 files changed

+31
-11
lines changed

3 files changed

+31
-11
lines changed

spring-modulith-runtime/src/main/java/org/springframework/modulith/runtime/autoconfigure/SpringModulithRuntimeAutoConfiguration.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
package org.springframework.modulith.runtime.autoconfigure;
1717

1818
import java.util.List;
19-
import java.util.concurrent.Executors;
2019
import java.util.concurrent.Future;
2120
import java.util.function.Supplier;
2221

@@ -31,6 +30,8 @@
3130
import org.springframework.context.ApplicationListener;
3231
import org.springframework.context.annotation.Bean;
3332
import org.springframework.context.annotation.Role;
33+
import org.springframework.core.task.AsyncTaskExecutor;
34+
import org.springframework.core.task.SimpleAsyncTaskExecutor;
3435
import org.springframework.modulith.ApplicationModuleInitializer;
3536
import org.springframework.modulith.core.ApplicationModule;
3637
import org.springframework.modulith.core.ApplicationModules;
@@ -49,6 +50,7 @@
4950
class SpringModulithRuntimeAutoConfiguration {
5051

5152
private static final Logger LOGGER = LoggerFactory.getLogger(SpringModulithRuntimeAutoConfiguration.class);
53+
private final AsyncTaskExecutor executor = new SimpleAsyncTaskExecutor();
5254

5355
@Bean
5456
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
@@ -63,7 +65,7 @@ SpringBootApplicationRuntime modulithsApplicationRuntime(ApplicationContext cont
6365
ApplicationModulesRuntime modulesRuntime(ApplicationRuntime runtime) {
6466

6567
var mainClass = runtime.getMainApplicationClass();
66-
var modules = Executors.newFixedThreadPool(1)
68+
var modules = executor
6769
.submit(() -> ApplicationModulesBootstrap.initializeApplicationModules(mainClass));
6870

6971
return new ApplicationModulesRuntime(toSupplier(modules), runtime);
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<configuration>
3+
4+
<include resource="org/springframework/boot/logging/logback/defaults.xml"/>
5+
<include resource="org/springframework/boot/logging/logback/console-appender.xml" />
6+
7+
<root level="INFO">
8+
<appender-ref ref="CONSOLE" />
9+
</root>
10+
11+
<logger name="org.springframework.modulith" level="DEBUG"/>
12+
<logger name="example" level="INFO" />
13+
14+
</configuration>

spring-modulith-runtime/src/test/java/org/springframework/modulith/runtime/autoconfigure/SpringModulithRuntimeAutoConfigurationIntegrationTests.java

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,30 +18,34 @@
1818
import static org.assertj.core.api.Assertions.*;
1919

2020
import org.junit.jupiter.api.Test;
21-
import org.springframework.beans.factory.annotation.Autowired;
21+
import org.springframework.boot.autoconfigure.AutoConfigurations;
2222
import org.springframework.boot.autoconfigure.SpringBootApplication;
23-
import org.springframework.boot.test.context.SpringBootTest;
24-
import org.springframework.context.ApplicationContext;
23+
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
2524
import org.springframework.modulith.runtime.ApplicationModulesRuntime;
2625
import org.springframework.modulith.runtime.ApplicationRuntime;
2726

2827
/**
29-
* Integration thest for {@link SpringModulithRuntimeAutoConfiguration}.
28+
* Integration test for {@link SpringModulithRuntimeAutoConfiguration}.
3029
*
3130
* @author Oliver Drotbohm
3231
*/
33-
@SpringBootTest
3432
class SpringModulithRuntimeAutoConfigurationIntegrationTests {
3533

3634
@SpringBootApplication
3735
static class SampleApp {}
3836

39-
@Autowired ApplicationContext context;
40-
4137
@Test // GH-87
4238
void bootstrapRegistersRuntimeInstances() {
4339

44-
assertThat(context.getBean(ApplicationRuntime.class)).isNotNull();
45-
assertThat(context.getBean(ApplicationModulesRuntime.class)).isNotNull();
40+
new ApplicationContextRunner()
41+
.withUserConfiguration(SampleApp.class)
42+
.withConfiguration(AutoConfigurations.of(SpringModulithRuntimeAutoConfiguration.class))
43+
.run(context -> {
44+
45+
assertThat(context.getBean(ApplicationRuntime.class)).isNotNull();
46+
assertThat(context.getBean(ApplicationModulesRuntime.class)).isNotNull();
47+
48+
context.close();
49+
});
4650
}
4751
}

0 commit comments

Comments
 (0)