0
# Web Application Types
1
2
Spring Boot's web application support provides automatic detection and configuration for different types of web applications, including servlet-based and reactive applications. It handles embedded servers, application contexts, and web-specific configuration.
3
4
## Capabilities
5
6
### Web Application Type Detection
7
8
Automatic detection and configuration of web application types based on classpath analysis.
9
10
```java { .api }
11
/**
12
* An enumeration of possible types of web application
13
*/
14
public enum WebApplicationType {
15
16
/**
17
* The application should not run as a web application and should not start an
18
* embedded web server
19
*/
20
NONE,
21
22
/**
23
* The application should run as a servlet-based web application and should start an
24
* embedded servlet web server
25
*/
26
SERVLET,
27
28
/**
29
* The application should run as a reactive web application and should start an
30
* embedded reactive web server
31
*/
32
REACTIVE;
33
34
private static final String[] SERVLET_INDICATOR_CLASSES = { "jakarta.servlet.Servlet",
35
"org.springframework.web.context.ConfigurableWebApplicationContext" };
36
37
private static final String[] WEBMVC_INDICATOR_CLASSES = { "org.springframework.web.servlet.DispatcherServlet",
38
"org.springframework.web.servlet.config.annotation.WebMvcConfigurer" };
39
40
private static final String[] WEBFLUX_INDICATOR_CLASSES = { "org.springframework.web.reactive.DispatcherHandler",
41
"org.springframework.http.server.reactive.HttpHandler" };
42
43
private static final String[] JERSEY_INDICATOR_CLASSES = { "org.glassfish.jersey.servlet.ServletContainer",
44
"org.glassfish.jersey.server.ResourceConfig" };
45
46
/**
47
* Deduces the web application type that should be used based on the classpath
48
* @return the deduced WebApplicationType
49
*/
50
public static WebApplicationType deduceFromClasspath() {
51
if (ClassUtils.isPresent(WEBFLUX_INDICATOR_CLASSES[0], null) && !ClassUtils.isPresent(WEBMVC_INDICATOR_CLASSES[0], null)
52
&& !ClassUtils.isPresent(JERSEY_INDICATOR_CLASSES[0], null)) {
53
return WebApplicationType.REACTIVE;
54
}
55
for (String className : SERVLET_INDICATOR_CLASSES) {
56
if (!ClassUtils.isPresent(className, null)) {
57
return WebApplicationType.NONE;
58
}
59
}
60
return WebApplicationType.SERVLET;
61
}
62
63
/**
64
* Deduces the web application type that should be used based on the provided ResourceLoader
65
* @param resourceLoader the resource loader
66
* @return the deduced WebApplicationType
67
*/
68
public static WebApplicationType deduceFromResourceLoader(ResourceLoader resourceLoader) {
69
if (resourceLoader instanceof WebApplicationContext && ((WebApplicationContext) resourceLoader).getServletContext() != null) {
70
return WebApplicationType.SERVLET;
71
}
72
return deduceFromClasspath();
73
}
74
}
75
```
76
77
**Usage Examples:**
78
79
```java
80
@SpringBootApplication
81
public class MyApplication {
82
83
public static void main(String[] args) {
84
SpringApplication app = new SpringApplication(MyApplication.class);
85
86
// Force specific web application type
87
app.setWebApplicationType(WebApplicationType.SERVLET);
88
89
// Or let Spring Boot detect automatically
90
WebApplicationType detectedType = WebApplicationType.deduceFromClasspath();
91
System.out.println("Detected web application type: " + detectedType);
92
93
app.run(args);
94
}
95
}
96
97
// Non-web application
98
@SpringBootApplication
99
public class BatchApplication {
100
101
public static void main(String[] args) {
102
SpringApplication app = new SpringApplication(BatchApplication.class);
103
app.setWebApplicationType(WebApplicationType.NONE); // No embedded server
104
app.run(args);
105
}
106
}
107
108
// Reactive web application
109
@SpringBootApplication
110
public class ReactiveApplication {
111
112
public static void main(String[] args) {
113
SpringApplication app = new SpringApplication(ReactiveApplication.class);
114
app.setWebApplicationType(WebApplicationType.REACTIVE); // Netty server
115
app.run(args);
116
}
117
}
118
```
119
120
### Servlet Web Server Context
121
122
Application context for servlet-based web applications with embedded server support.
123
124
```java { .api }
125
/**
126
* A WebApplicationContext that can be used to bootstrap itself from a contained
127
* ServletWebServerFactory bean
128
*/
129
public class ServletWebServerApplicationContext extends GenericWebApplicationContext
130
implements ConfigurableWebServerApplicationContext {
131
132
/**
133
* Create a new ServletWebServerApplicationContext
134
*/
135
public ServletWebServerApplicationContext();
136
137
/**
138
* Create a new ServletWebServerApplicationContext with the given DefaultListableBeanFactory
139
* @param beanFactory the DefaultListableBeanFactory instance to use for this context
140
*/
141
public ServletWebServerApplicationContext(DefaultListableBeanFactory beanFactory);
142
143
/**
144
* Returns the ServletWebServerFactory that should be used to create the embedded
145
* ServletWebServer. By default this method searches for a suitable bean in the
146
* context itself
147
* @return a ServletWebServerFactory (never null)
148
*/
149
protected ServletWebServerFactory getWebServerFactory();
150
151
/**
152
* Return the WebServer that was created by the context or null if the server has
153
* not yet been created
154
* @return the web server
155
*/
156
public WebServer getWebServer();
157
158
/**
159
* Returns the ServletContext that should be used with the embedded web server or
160
* null if the context is not running
161
* @return the servlet context
162
*/
163
public ServletContext getServletContext();
164
}
165
166
/**
167
* A WebApplicationContext that can create and manage an embedded web server
168
*/
169
public interface ConfigurableWebServerApplicationContext extends ConfigurableApplicationContext, WebServerApplicationContext {
170
171
/**
172
* Set the server namespace of the context
173
* @param serverNamespace the server namespace
174
*/
175
void setServerNamespace(String serverNamespace);
176
}
177
178
/**
179
* Interface to be implemented by application contexts that create and manage the
180
* lifecycle of an embedded web server
181
*/
182
public interface WebServerApplicationContext extends ApplicationContext {
183
184
/**
185
* Returns the WebServer that has been created by the context or null if the
186
* server has not yet been created
187
* @return the web server
188
*/
189
WebServer getWebServer();
190
191
/**
192
* Returns the namespace that has been set on the server or null if no namespace
193
* has been set
194
* @return the server namespace
195
*/
196
String getServerNamespace();
197
}
198
```
199
200
**Usage Examples:**
201
202
```java
203
@Component
204
public class WebServerInfoProvider {
205
206
@Autowired
207
private ServletWebServerApplicationContext context;
208
209
@EventListener
210
public void onApplicationReady(ApplicationReadyEvent event) {
211
WebServer webServer = context.getWebServer();
212
if (webServer != null) {
213
int port = webServer.getPort();
214
System.out.println("Server started on port: " + port);
215
}
216
217
ServletContext servletContext = context.getServletContext();
218
if (servletContext != null) {
219
String contextPath = servletContext.getContextPath();
220
System.out.println("Context path: " + contextPath);
221
}
222
}
223
}
224
```
225
226
### Reactive Web Server Context
227
228
Application context for reactive web applications with embedded server support.
229
230
```java { .api }
231
/**
232
* A WebApplicationContext that can be used to bootstrap itself from a contained
233
* ReactiveWebServerFactory bean
234
*/
235
public class ReactiveWebServerApplicationContext extends GenericReactiveWebApplicationContext
236
implements ConfigurableWebServerApplicationContext {
237
238
/**
239
* Create a new ReactiveWebServerApplicationContext
240
*/
241
public ReactiveWebServerApplicationContext();
242
243
/**
244
* Create a new ReactiveWebServerApplicationContext with the given DefaultListableBeanFactory
245
* @param beanFactory the DefaultListableBeanFactory instance to use for this context
246
*/
247
public ReactiveWebServerApplicationContext(DefaultListableBeanFactory beanFactory);
248
249
/**
250
* Returns the ReactiveWebServerFactory that should be used to create the embedded
251
* ReactiveWebServer. By default this method searches for a suitable bean in the
252
* context itself
253
* @return a ReactiveWebServerFactory (never null)
254
*/
255
protected ReactiveWebServerFactory getWebServerFactory();
256
257
/**
258
* Return the WebServer that was created by the context or null if the server has
259
* not yet been created
260
* @return the web server
261
*/
262
public WebServer getWebServer();
263
}
264
```
265
266
### Web Server Factories
267
268
Interfaces for creating different types of embedded web servers.
269
270
```java { .api }
271
/**
272
* Factory interface that can be used to create a WebServer
273
*/
274
@FunctionalInterface
275
public interface WebServerFactory {
276
277
/**
278
* Gets a new fully configured but paused WebServer instance. Clients should not be
279
* able to connect to the returned server until WebServer.start() is called (which
280
* happens when the ApplicationContext has been fully refreshed)
281
* @param port the port to listen on, or 0 to use any available port
282
* @return a fully configured and started WebServer (will never be null)
283
*/
284
WebServer getWebServer(int port);
285
}
286
287
/**
288
* Factory interface that can be used to create a reactive WebServer
289
*/
290
@FunctionalInterface
291
public interface ReactiveWebServerFactory extends WebServerFactory {
292
293
/**
294
* Gets a new fully configured but paused WebServer instance. Clients should not be
295
* able to connect to the returned server until WebServer.start() is called
296
* @param httpHandler the HTTP handler in charge of processing requests
297
* @return a fully configured and started WebServer (will never be null)
298
*/
299
WebServer getWebServer(HttpHandler httpHandler);
300
}
301
302
/**
303
* Factory interface that can be used to create a servlet WebServer
304
*/
305
@FunctionalInterface
306
public interface ServletWebServerFactory extends WebServerFactory {
307
308
/**
309
* Gets a new fully configured but paused WebServer instance. Clients should not be
310
* able to connect to the returned server until WebServer.start() is called
311
* @param initializers ServletContextInitializers that should be applied as the
312
* server starts
313
* @return a fully configured and started WebServer (will never be null)
314
*/
315
WebServer getWebServer(ServletContextInitializer... initializers);
316
}
317
```
318
319
### Web Server Interface
320
321
Core interface for embedded web servers.
322
323
```java { .api }
324
/**
325
* Simple interface that represents a fully configured web server (e.g. Tomcat, Jetty, Netty)
326
*/
327
public interface WebServer {
328
329
/**
330
* Starts the web server. Calling this method on an already started server has no effect
331
* @throws WebServerException if the server cannot be started
332
*/
333
void start() throws WebServerException;
334
335
/**
336
* Stops the web server. Calling this method on an already stopped server has no effect
337
* @throws WebServerException if the server cannot be stopped
338
*/
339
void stop() throws WebServerException;
340
341
/**
342
* Return the port this server is listening on
343
* @return the port (or -1 if none)
344
*/
345
int getPort();
346
347
/**
348
* Initiates a graceful shutdown of the web server. Handling of new requests is
349
* prevented and the given callback is invoked at the end of the attempt. The
350
* attempt can be explicitly ended by invoking stop(). The default
351
* implementation invokes the callback immediately with GracefulShutdownResult.IMMEDIATE,
352
* i.e. to indicate that no attempt was made to gracefully shutdown the server
353
* @param callback the callback to invoke when the graceful shutdown completes
354
*/
355
default void shutDownGracefully(GracefulShutdownCallback callback) {
356
callback.shutdownComplete(GracefulShutdownResult.IMMEDIATE);
357
}
358
}
359
360
/**
361
* Callback interface that can be used to be notified when a graceful shutdown completes
362
*/
363
@FunctionalInterface
364
public interface GracefulShutdownCallback {
365
366
/**
367
* Graceful shutdown has completed with the given result
368
* @param result the result of the shutdown
369
*/
370
void shutdownComplete(GracefulShutdownResult result);
371
}
372
373
/**
374
* The result of a graceful shutdown request
375
*/
376
public enum GracefulShutdownResult {
377
378
/**
379
* Requests remained active at the end of the grace period
380
*/
381
REQUESTS_ACTIVE,
382
383
/**
384
* The server was idle with no active requests
385
*/
386
IDLE,
387
388
/**
389
* The shutdown was aborted typically due to ongoing new requests
390
*/
391
ABORTED,
392
393
/**
394
* No attempt was made to gracefully shutdown the server
395
*/
396
IMMEDIATE
397
}
398
```
399
400
**Usage Examples:**
401
402
```java
403
@Component
404
public class WebServerManager {
405
406
@Autowired
407
private WebServerApplicationContext context;
408
409
@EventListener
410
public void handleContextRefresh(ContextRefreshedEvent event) {
411
WebServer webServer = context.getWebServer();
412
System.out.println("Web server type: " + webServer.getClass().getSimpleName());
413
System.out.println("Server port: " + webServer.getPort());
414
}
415
416
@PreDestroy
417
public void gracefulShutdown() {
418
WebServer webServer = context.getWebServer();
419
if (webServer != null) {
420
System.out.println("Initiating graceful shutdown...");
421
webServer.shutDownGracefully(result -> {
422
System.out.println("Graceful shutdown completed with result: " + result);
423
});
424
}
425
}
426
}
427
428
// Custom web server factory configuration
429
@Configuration
430
public class WebServerConfig {
431
432
@Bean
433
public TomcatServletWebServerFactory servletWebServerFactory() {
434
TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory();
435
factory.setPort(8080);
436
factory.setContextPath("/api");
437
factory.addConnectorCustomizers(connector -> {
438
connector.setMaxThreads(200);
439
});
440
return factory;
441
}
442
}
443
```
444
445
### Web Application Configuration
446
447
Core Spring Boot annotation combining multiple configuration annotations.
448
449
```java { .api }
450
/**
451
* Indicates a configuration class that declares one or more @Bean methods and also
452
* triggers auto-configuration and component scanning. This is a convenience annotation
453
* that is equivalent to declaring @Configuration, @EnableAutoConfiguration and @ComponentScan
454
*/
455
@Target(ElementType.TYPE)
456
@Retention(RetentionPolicy.RUNTIME)
457
@Documented
458
@Inherited
459
@SpringBootConfiguration
460
@EnableAutoConfiguration
461
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
462
@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
463
public @interface SpringBootApplication {
464
465
/**
466
* Exclude specific auto-configuration classes such that they will never be applied
467
* @return the classes to exclude
468
*/
469
@AliasFor(annotation = EnableAutoConfiguration.class)
470
Class<?>[] exclude() default {};
471
472
/**
473
* Exclude specific auto-configuration class names such that they will never be applied
474
* @return the class names to exclude
475
*/
476
@AliasFor(annotation = EnableAutoConfiguration.class)
477
String[] excludeName() default {};
478
479
/**
480
* Base packages to scan for annotated components
481
* @return base packages for component scanning
482
*/
483
@AliasFor(annotation = ComponentScan.class, attribute = "basePackages")
484
String[] scanBasePackages() default {};
485
486
/**
487
* Type-safe alternative to scanBasePackages() for specifying the packages to scan
488
* @return base package classes for component scanning
489
*/
490
@AliasFor(annotation = ComponentScan.class, attribute = "basePackageClasses")
491
Class<?>[] scanBasePackageClasses() default {};
492
493
/**
494
* Whether @Bean methods should get proxied in order to enforce bean lifecycle behavior
495
* @return whether to proxy @Bean methods
496
*/
497
@AliasFor(annotation = Configuration.class)
498
boolean proxyBeanMethods() default true;
499
}
500
501
/**
502
* Indicates that a class provides Spring Boot application @Configuration
503
*/
504
@Target(ElementType.TYPE)
505
@Retention(RetentionPolicy.RUNTIME)
506
@Documented
507
@Configuration
508
@Indexed
509
public @interface SpringBootConfiguration {
510
511
/**
512
* Whether @Bean methods should get proxied in order to enforce bean lifecycle behavior
513
* @return whether to proxy @Bean methods
514
*/
515
@AliasFor(annotation = Configuration.class)
516
boolean proxyBeanMethods() default true;
517
}
518
```
519
520
**Usage Examples:**
521
522
```java
523
// Basic Spring Boot application
524
@SpringBootApplication
525
public class MyWebApplication {
526
public static void main(String[] args) {
527
SpringApplication.run(MyWebApplication.class, args);
528
}
529
}
530
531
// Customized component scanning
532
@SpringBootApplication(scanBasePackages = {"com.example.controllers", "com.example.services"})
533
public class RestApiApplication {
534
public static void main(String[] args) {
535
SpringApplication.run(RestApiApplication.class, args);
536
}
537
}
538
539
// Excluding specific auto-configurations
540
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class, JpaRepositoriesAutoConfiguration.class})
541
public class NonDatabaseApplication {
542
public static void main(String[] args) {
543
SpringApplication.run(NonDatabaseApplication.class, args);
544
}
545
}
546
547
// Using SpringBootConfiguration separately
548
@SpringBootConfiguration
549
@EnableAutoConfiguration
550
@ComponentScan
551
public class CustomApplication {
552
public static void main(String[] args) {
553
SpringApplication.run(CustomApplication.class, args);
554
}
555
}
556
```