1. 程式人生 > >【Spring Boot】(18)、Spring Boot配置嵌入式Servlet容器

【Spring Boot】(18)、Spring Boot配置嵌入式Servlet容器

Spring Boot預設使用Tomcat作為嵌入式的Servlet容器,只要引入了spring-boot-start-web依賴,則預設是用Tomcat作為Servlet容器:


1、定製和修改Servlet容器的相關配置

1)、修改和server有關的配置(ServerProperties,它其實也是EmbeddedServletContainerCustomizer的子類):

server.port=8080
server.context-path=/

# tomcat相關設定
server.tomcat.uri-encoding=UTF-8

2)、編寫EmbeddedServletContainerCustomizer

(嵌入式的Servlet容器的定製器)來修改Servlet容器的配置,返回一個自定義的定製器Bean:

@Bean
public EmbeddedServletContainerCustomizer embeddedServletContainerCustomizer(){
    //定製嵌入式的Servlet容器相關的屬性配置
    return container -> container.setPort(8083);
}


2、註冊Servlet容器的三大元件(Servlet、Filter、Listener)

        由於Spring Boot預設是以jar包的形式啟動嵌入式的Servlet容器,從而來啟動Spring Boot的web應用,沒有web.xml檔案。

以前編寫三大元件大多都需要在web.xml檔案中進行配置(使用註解除外,@WebServlet@WebListener@WebFilter),而現在使用SpringBoot作為框架,如果需要編寫三大元件,則需要使用配置的方式進行註冊。

要註冊三大元件:

  • ServletRegistrationBean:註冊Servlet

//Servlet定義
public class MyServlet extends HttpServlet {

	@Override
	protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		System.out.println("這是一個servlet請求...");
	}
}

//Servlet註冊
@Configuration
public class MyServletConfig {

	//註冊Servlet
	@Bean
	public ServletRegistrationBean myServlet(){
		return new ServletRegistrationBean(new MyServlet(), "/myServlet");
	}
}


  • FilterRegistrationBean:註冊Filter
//Filter定義
public class MyFilter implements Filter {
	@Override
	public void init(FilterConfig filterConfig) throws ServletException {

	}

	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
		System.out.println("MyFilter process...");
		//放行
		chain.doFilter(request, response);
	}

	@Override
	public void destroy() {

	}
}

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


  • ServletListenerRegistrationBean:註冊Listener
//Listener定義
public class MyListener implements ServletContextListener {
	@Override
	public void contextInitialized(ServletContextEvent sce) {
		System.out.println("contextInitialized...web啟動");
	}

	@Override
	public void contextDestroyed(ServletContextEvent sce) {
		System.out.println("contextDestroyed...web銷燬");
	}
}

//Listener註冊
@Bean
public ServletListenerRegistrationBean myListener(){
    return new ServletListenerRegistrationBean<>(new MyListener());
}


    最熟悉的莫過於,在Spring Boot在自動配置SpringMVC的時候,會自動註冊SpringMVC前端控制器:DispatcherServlet,該控制器主要在DispatcherServletAutoConfiguration自動配置類中進行註冊的。

@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE)
@Configuration
@ConditionalOnWebApplication
@ConditionalOnClass(DispatcherServlet.class)
@AutoConfigureAfter(EmbeddedServletContainerAutoConfiguration.class)
public class DispatcherServletAutoConfiguration {
    
    //other code...
    
    public static final String DEFAULT_DISPATCHER_SERVLET_BEAN_NAME = "dispatcherServlet";
    
    private String servletPath = "/";
    
    @Bean(name = DEFAULT_DISPATCHER_SERVLET_REGISTRATION_BEAN_NAME)
                @ConditionalOnBean(value = DispatcherServlet.class, name = DEFAULT_DISPATCHER_SERVLET_BEAN_NAME)
    public ServletRegistrationBean dispatcherServletRegistration(
        DispatcherServlet dispatcherServlet) {
        ServletRegistrationBean registration = new ServletRegistrationBean(
            dispatcherServlet, this.serverProperties.getServletMapping());
        //預設攔截 / 所有請求,包括靜態資源,但是不攔截jsp請求;/*會攔截jsp
        //可以通過修改server.servlet-path來修改預設的攔截請求
        registration.setName(DEFAULT_DISPATCHER_SERVLET_BEAN_NAME);
        registration.setLoadOnStartup(
            this.webMvcProperties.getServlet().getLoadOnStartup());
        if (this.multipartConfig != null) {
            registration.setMultipartConfig(this.multipartConfig);
        }
        return registration;
    }
}

    正如原始碼中提到,它使用ServletRegistrationBean將dispatcherServlet進行註冊,並將urlPattern設為了/,這樣就類似原來的web.xml中配置的dispatcherServlet。

<servlet>
    <servlet-name>dispatcherServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>dispatcherServlet</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>


3、其他Servlet容器

Spring Boot預設支援TomcatJetty,和Undertow作為底層容器。如圖:


而Spring Boot預設使用Tomcat,一旦引入spring-boot-starter-web模組,就預設使用Tomcat容器。

切換其他Servlet容器:

1)、將tomcat依賴移除掉

2)、引入其他Servlet容器依賴

引入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>

切換了Servlet容器後,只是以server開頭的配置不一樣外,其他都類似。


====================打個廣告,歡迎關注====================

QQ:
412425870
微信公眾號:Cay課堂

csdn部落格:
http://blog.csdn.net/caychen
碼雲:
https://gitee.com/caychen/
github:
https://github.com/caychen

點選群號或者掃描二維碼即可加入QQ群:

328243383(1群)




點選群號或者掃描二維碼即可加入QQ群:

180479701(2群)