Spring Boot |配置和切換嵌入式Servlet容器


在使用SpringBoot之前,需要將Web應用打成war包,在外部配置好Tomcat的環境(Tomcat就是Servlet的容器),將web應用放在Tomcat上,在外部啓動Tomcat;使用了SpringBoot時,無需使用外部Tomcat環境,原因就在於SpringBoot自帶了嵌入式的Tomcat。本文詳細介紹如何配置嵌入式Servlet容器。

一、配置嵌入式Servlet容器

SpringBoot默認使用Tomcat作爲嵌入式的Servlet容器,可以在IDEA的pom文件中showDependencies,查看依賴圖:

在這裏插入圖片描述
由依賴圖可以發現SpringBoot默認使用了嵌入式的Servlet容器。這就出現了一個問題,之前使用外置的Tomcat如果想定製或優化,可以在conf目錄的server.xml文件中修改。使用了SpringBoot後,可以在application.properties文件中定製和修改與server相關的配置。實際上修改的是ServerProperties類的屬性。

  • 通用的Servlet容器可以設置爲server.xxx
  • Tomcat相關的可以設置爲tomcat.xxx
配置 說明
server.port=8081 設置項目訪問路徑
server.servlet.context-path=/crud 修改訪問映射
server.tomcat.uri‐encoding=UTF‐8 設置編碼格式

除了在application.properties文件中修改配置,還可以像下面的代碼這樣編寫一個嵌入式Servlet容器定製器 ,來修改Servlet容器的配置,兩種方式雖然實現上不同,但底層都是相同的原理。

@Configuration
public class MyServerConfig {
    /**
     * 配置嵌入式Servlet容器
     */
    @Bean
    public WebServerFactoryCustomizer<ConfigurableWebServerFactory> webServerFactoryCustomizer(){
        return new WebServerFactoryCustomizer<ConfigurableWebServerFactory>(){
            //定製嵌入式Servlet容器相關的規則
            @Override
            public void customize(ConfigurableWebServerFactory factory) {
                factory.setPort(8083);
            }
        };
    }
}

二、註冊Servlet三大組件

SpringBoot默認是以jar包的方式啓動嵌入式的Servlet容器,進而啓動SpringBoot的web應用,所以沒有web.xml文件。(標準的Web目錄結構,三大組件配置在src/main/webapp/WEB-INF/web.xml)。

Servlet三大組件 註冊方式 自己的組件需要做的工作
Servlet ServletRegistrationBean 繼承HttpServlet
Filter FilterRegistrationBean 實現Filter
Listener ServletListenerRegistrationBean 實現ServletContextListener

2.1 使用ServletRegistrationBean註冊Servlet

@Configuration
public class MyServerConfig {
    /**
     * 註冊Servlet:使用ServletRegistrationBean
     */
    @Bean
    public ServletRegistrationBean myServlet(){
        ServletRegistrationBean registrationBean = new ServletRegistrationBean(new MyServlet(),"/myServlet");
        return registrationBean;
    }
}

創建自己的Servlet需要實現HttpServlet接口。

public class MyServlet extends HttpServlet {
    //處理GET請求
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req, resp);
    }

    //處理POST請求
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
       resp.getWriter().write("Hello MyServlet");
    }
}

2.2 使用FilterRegistrationBean註冊Filter

@Configuration
public class MyServerConfig {
    /**
     * 註冊Filter:使用FilterRegistrationBean
     */
    @Bean
    public FilterRegistrationBean myFilter() {
        FilterRegistrationBean registrationBean = new FilterRegistrationBean();
        registrationBean.setFilter(new MyFilter());
        registrationBean.setUrlPatterns(Arrays.asList("/hello", "/myServlet"));
        return registrationBean;
    }
}

創建自己的Filter需要實現Filter接口。

public class MyFilter implements Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void destroy() {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("MyFilter process...");
        filterChain.doFilter(servletRequest,servletResponse);
    }
}

2.3 使用ServletListenerRegistrationBean註冊Listener

@Configuration
public class MyServerConfig {
    /**
     * 註冊Listener:使用ServletListenerRegistrationBean
     */
    @Bean
    public ServletListenerRegistrationBean myListener() {
        ServletListenerRegistrationBean<MyListener> registrationBean = new ServletListenerRegistrationBean<MyListener>(new MyListener());
        return registrationBean;
    }
}

創建自己的Listener需要實現ServletContextListener接口。

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項目銷燬");
    }
}

三、使用其他嵌入式Servlet容器

SpringBoot默認使用Tomcat,除此之外,SpringBoot還支持Jetty容器(適合長鏈接應用,)、Undertow容器(不支持JSP,但是性能高、非阻塞、併發性能好)

在這裏插入圖片描述

3.1 切換爲Jetty容器

打開pom文件的依賴圖,excloud掉spring-boot-starter-tomcat之後,引入Jetty容器。

        <!--引入Jetty容器-->
        <dependency>
            <artifactId>spring-boot-starter-jetty</artifactId>
            <groupId>org.springframework.boot</groupId>
        </dependency>

等待加載完畢,就可以看到生成了Jetty的依賴。
在這裏插入圖片描述

3.2 切換爲Undertow容器

打開pom文件的依賴圖,excloud掉spring-boot-starter-tomcat之後,引入Undertow容器。

  		<!--引入Undertow容器-->
        <dependency>
            <artifactId>spring-boot-starter-undertow</artifactId>
            <groupId>org.springframework.boot</groupId>
        </dependency>

等待加載完畢,就可以看到生成了Undertow的依賴。
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章