|
1 | 1 | /*
|
2 |
| - * Copyright 2012-2023 the original author or authors. |
| 2 | + * Copyright 2012-2024 the original author or authors. |
3 | 3 | *
|
4 | 4 | * Licensed under the Apache License, Version 2.0 (the "License");
|
5 | 5 | * you may not use this file except in compliance with the License.
|
|
28 | 28 | import jakarta.servlet.ServletException;
|
29 | 29 | import org.apache.commons.logging.Log;
|
30 | 30 | import org.apache.commons.logging.LogFactory;
|
| 31 | +import reactor.core.scheduler.Schedulers; |
31 | 32 |
|
32 | 33 | import org.springframework.boot.SpringApplication;
|
33 | 34 | import org.springframework.boot.builder.ParentContextApplicationContextInitializer;
|
|
44 | 45 | import org.springframework.core.annotation.MergedAnnotations.SearchStrategy;
|
45 | 46 | import org.springframework.core.env.ConfigurableEnvironment;
|
46 | 47 | import org.springframework.util.Assert;
|
| 48 | +import org.springframework.util.ClassUtils; |
47 | 49 | import org.springframework.web.WebApplicationInitializer;
|
48 | 50 | import org.springframework.web.context.ConfigurableWebEnvironment;
|
49 | 51 | import org.springframework.web.context.ContextLoaderListener;
|
|
69 | 71 | * @author Dave Syer
|
70 | 72 | * @author Phillip Webb
|
71 | 73 | * @author Andy Wilkinson
|
| 74 | + * @author Brian Clozel |
72 | 75 | * @since 2.0.0
|
73 | 76 | * @see #configure(SpringApplicationBuilder)
|
74 | 77 | */
|
75 | 78 | public abstract class SpringBootServletInitializer implements WebApplicationInitializer {
|
76 | 79 |
|
| 80 | + private static final boolean REACTOR_PRESENT = ClassUtils.isPresent("reactor.core.scheduler.Schedulers", |
| 81 | + SpringBootServletInitializer.class.getClassLoader()); |
| 82 | + |
77 | 83 | protected Log logger; // Don't initialize early
|
78 | 84 |
|
79 | 85 | private boolean registerErrorPageFilter = true;
|
@@ -125,6 +131,20 @@ protected void deregisterJdbcDrivers(ServletContext servletContext) {
|
125 | 131 | }
|
126 | 132 | }
|
127 | 133 |
|
| 134 | + /** |
| 135 | + * Shuts down the reactor {@link Schedulers} that were initialized by |
| 136 | + * {@code Schedulers.boundedElastic()} (or similar). The default implementation |
| 137 | + * {@link Schedulers#shutdownNow()} schedulers if they were initialized on this web |
| 138 | + * application's class loader. |
| 139 | + * @param servletContext the web application's servlet context |
| 140 | + * @since 3.4.0 |
| 141 | + */ |
| 142 | + protected void shutDownSharedReactorSchedulers(ServletContext servletContext) { |
| 143 | + if (Schedulers.class.getClassLoader() == servletContext.getClassLoader()) { |
| 144 | + Schedulers.shutdownNow(); |
| 145 | + } |
| 146 | + } |
| 147 | + |
128 | 148 | protected WebApplicationContext createRootApplicationContext(ServletContext servletContext) {
|
129 | 149 | SpringApplicationBuilder builder = createSpringApplicationBuilder();
|
130 | 150 | builder.main(getClass());
|
@@ -248,6 +268,10 @@ public void contextDestroyed(ServletContextEvent event) {
|
248 | 268 | finally {
|
249 | 269 | // Use original context so that the classloader can be accessed
|
250 | 270 | deregisterJdbcDrivers(this.servletContext);
|
| 271 | + // Shut down shared reactor schedulers tied to this classloader |
| 272 | + if (REACTOR_PRESENT) { |
| 273 | + shutDownSharedReactorSchedulers(this.servletContext); |
| 274 | + } |
251 | 275 | }
|
252 | 276 | }
|
253 | 277 |
|
|
0 commit comments