SpringBoot Learning Notes-010

4.8. Configuring an embedded Servlet container

SpringBoot defaults to Tomcat as the embedded Servlet container: version 9.0.31

Question?

4.8.1. How to customize and modify the configuration of the Servlet container

1. Modify server-related configurations (see parameters) ServerProperties Class;

server.port=8081
server.servlet.context-path= /ep
server.tomcat.uri-encoding= UTF-8

#General Servlet Container Settings
server.xxx
#Tomcat settings
server.tomcat.xxx

2. You can modify the configuration of the Servlet container by registering a class that implements the WebServerFactoryCustomizer interface

import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory;
import org.springframework.stereotype.Component;

@Component
public class CustomizationBean implements WebServerFactoryCustomizer<ConfigurableServletWebServerFactory> {

    @Override
    public void customize(ConfigurableServletWebServerFactory server) {
        server.setPort(9000);
    }

}

Other ways, see Official Documents

4.8.2, Register Servlet three components [Servlet, Filter, Listener]

Since SpringBoot starts an embedded Servlet container as a jar package by default to start a SpringBoot web application, there is no web.xml file.

Registering the three components uses the following method to register through the configuration class:

ServletRegistrationBean

@Bean
public ServletRegistrationBean myServlet(){
    ServletRegistrationBean registrationBean = new ServletRegistrationBean(new MyServlet(),"/myServlet");
    registrationBean.setLoadOnStartup(1);
    return registrationBean;
}

FilterRegistrationBean

@Bean
public FilterRegistrationBean myFilter(){
    FilterRegistrationBean registrationBean = new FilterRegistrationBean();
    registrationBean.setFilter(new MyFilter());
    registrationBean.setUrlPatterns(Arrays.asList("/hello","/myServlet"));
    return registrationBean;
}

ServletListenerRegistrationBean

@Bean
public ServletListenerRegistrationBean myListener(){
    ServletListenerRegistrationBean<MyListener> registrationBean = new ServletListenerRegistrationBean<>(new MyListener());
    return registrationBean;
}

Add three components annotated:

Annotate the corresponding classes: @WebServlet, @WebFilter, @WebListener, to register directly in the container. Note that @ServletComponentScan must be added to the main configuration class.

When SpringBoot helped us automatically configure SpringMVC, it automatically registered the front-end controller Dispatcher Servlet for SpringMVC.

In Dispatcher ServletAutoConfiguration:

@Bean(name = DEFAULT_DISPATCHER_SERVLET_REGISTRATION_BEAN_NAME)
@ConditionalOnBean(value = DispatcherServlet.class, name = DEFAULT_DISPATCHER_SERVLET_BEAN_NAME)
public DispatcherServletRegistrationBean dispatcherServletRegistration(DispatcherServlet dispatcherServlet, WebMvcProperties webMvcProperties, ObjectProvider<MultipartConfigElement> 				multipartConfig) {
    DispatcherServletRegistrationBean registration = new DispatcherServletRegistrationBean(dispatcherServlet,webMvcProperties.getServlet().getPath());
    
    //webMvcProperties.getServlet().getPath(), default intercept: /All requests, including static resources, but not JSPs, /* will intercept JSPs
    //Request paths intercepted by default by the SpringMVC front-end controller can be modified through server.servlet.Path
    registration.setName(DEFAULT_DISPATCHER_SERVLET_BEAN_NAME);
    registration.setLoadOnStartup(webMvcProperties.getServlet().getLoadOnStartup());
    multipartConfig.ifAvailable(registration::setMultipartConfig);
    return registration;
}

4.8.3, Replace with other embedded Servlet containers

Tomcat (default)

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

Jetty

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <exclusions>
        <exclusion>
            <artifactId>spring-boot-starter-tomcat</artifactId>
            <groupId>org.springframework.boot</groupId>
        </exclusion>
    </exclusions>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jetty</artifactId>
</dependency>

undertow

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <exclusions>
        <exclusion>
            <artifactId>spring-boot-starter-tomcat</artifactId>
            <groupId>org.springframework.boot</groupId>
        </exclusion>
    </exclusions>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-undertow</artifactId>
</dependency>

4.8.4, Embedded Servlet Container Automatic Configuration Principle

To be perfected...

4.8.5, Embedded Servlet Container Startup Principle

Get the embedded Servlet container factory:

1. SpringBoot Application Start run Run Method

2. refreshContext; SpringRoot refreshes the IOC container [Create IOC container objects and initialize the container to create each one in the container Components]; if the web application creates AnnotationConfigServletWebServerApplicationContextt, if the REACTIVE application creates AnnotationConfigReactiveWebServerApplicationContext Otherwise: AnnotationConfigApplicationContext

3. refreshContext; refresh the IOC container you just created

@Override
	public void refresh() throws BeansException, IllegalStateException {
		synchronized (this.startupShutdownMonitor) {
			// Prepare this context for refreshing.
			prepareRefresh();

			// Tell the subclass to refresh the internal bean factory.
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

			// Prepare the bean factory for use in this context.
			prepareBeanFactory(beanFactory);

			try {
				// Allows post-processing of the bean factory in context subclasses.
				postProcessBeanFactory(beanFactory);

				// Invoke factory processors registered as beans in the context.
				invokeBeanFactoryPostProcessors(beanFactory);

				// Register bean processors that intercept bean creation.
				registerBeanPostProcessors(beanFactory);

				// Initialize message source for this context.
				initMessageSource();

				// Initialize event multicaster for this context.
				initApplicationEventMulticaster();

				// Initialize other special beans in specific context subclasses.
				onRefresh();

				// Check for listener beans and register them.
				registerListeners();

				// Instantiate all remaining (non-lazy-init) singletons.
				finishBeanFactoryInitialization(beanFactory);

				// Last step: publish corresponding event.
				finishRefresh();
			}

			catch (BeansException ex) {
				if (logger.isWarnEnabled()) {
					logger.warn("Exception encountered during context initialization - " +
							"cancelling refresh attempt: " + ex);
				}

				// Destroy already created singletons to avoid dangling resources.
				destroyBeans();

				// Reset 'active' flag.
				cancelRefresh(ex);

				// Propagate exception to caller.
				throw ex;
			}

			finally {
				// Reset common introspection caches in Spring's core, since we
				// might not ever need metadata for singleton beans anymore...
				resetCommonCaches();
			}
		}
	}

4. onRefresh(); the ioc container of the web overrides the onRefresh method

5. The webioc container creates an embedded Servlet container; createWebServer();

6. Get the Servlet container factory:

ServletWebServerFactory factory = getWebServerFactory();

Get the ServletWebServerFactory component from the ioc container; **ServletWebServerFactory** Create the object, and the post processor - this is the object - gets all the customizers to pre-customize the configuration of the Servlet container;

7. Use a container factory to obtain a WebServlet container: this.webServer = factory.getWebServer(getSelfInitializer());

8. An embedded Servlet container creates objects and starts the Servletp container;

Start the embedded Servlet container first, then fetch the remaining objects in the ioc container that have not been created.

IOC Container Launch Create Embedded Servlet Container

Tags: Programming Spring Tomcat SpringBoot Jetty

Posted on Mon, 23 Mar 2020 13:06:36 -0400 by php_dev_101