SpringBoot Boot內嵌Tomcat


Spring Boot:

SpringBoot-start-web 里面依賴的環境中

 

如果是外部的Tomcat 容器,可以通過修改config進行配置

內嵌的呢?

 

如何定制和修改Servlet容器的相關配置;

1、修改和server有關的配置(ServerProperties類【也是EmbeddedServletContainerCustomizer】);

經常用的: 

server.port=8081
server.context‐path=/crud
server.tomcat.uri‐encoding=UTF‐8

//通用的Servlet容器設置 server.xxx //Tomcat的設置 server.tomcat.xxx 最大連接數等等   

 

原理:

@ConfigurationProperties(prefix = "server", ignoreUnknownFields = true)
public class ServerProperties {

    /**
     * Server HTTP port.
     */
    private Integer port;

    /**
     * Network address to which the server should bind.
     */
    private InetAddress address;

    @NestedConfigurationProperty
    private final ErrorProperties error = new ErrorProperties();

    /**
     * Whether X-Forwarded-* headers should be applied to the HttpRequest.
     */
    private Boolean useForwardHeaders;

    /**
     * Value to use for the Server response header (if empty, no header is sent).
     */
    private String serverHeader;

    /**
     * Maximum size of the HTTP message header.
     */
    private DataSize maxHttpHeaderSize = DataSize.ofKilobytes(8);

    /**
     * Time that connectors wait for another HTTP request before closing the connection.
     * When not set, the connector's container-specific default is used. Use a value of -1
     * to indicate no (that is, an infinite) timeout.
     */
    private Duration connectionTimeout;

    @NestedConfigurationProperty
    private Ssl ssl;

    @NestedConfigurationProperty
    private final Compression compression = new Compression();

    @NestedConfigurationProperty
    private final Http2 http2 = new Http2();

    private final Servlet servlet = new Servlet();

    private final Tomcat tomcat = new Tomcat();

    private final Jetty jetty = new Jetty();

    private final Undertow undertow = new Undertow();

    public Integer getPort() {
        return this.port;
    }

    public void setPort(Integer port) {
        this.port = port;
    }

    public InetAddress getAddress() {
        return this.address;
    }

 

 

2、編寫一個EmbeddedServletContainerCustomizer:嵌入式的Servlet容器的定制器;來修改Servlet容器的配置 (已經過時了)

@Bean  //一定要將這個定制器加入到容器中
public EmbeddedServletContainerCustomizer embeddedServletContainerCustomizer(){
    return new EmbeddedServletContainerCustomizer() {
        //定制嵌入式的Servlet容器相關的規則
        @Override
        public void customize(ConfigurableEmbeddedServletContainer container) {
            container.setPort(8083);
        }
    };
}

 

 

注冊Servlet的三大組件 Servlet  Filter  Listener


 

Spring boot 默認以jar包的方式 啟動嵌入式tomcat,而不是標准的web應用。 webapp/WEB-INF/web.xml

沒有web.xml 也可以注冊哦

 

ServletRegistrationBean

  

//注冊三大組件
@Bean
public ServletRegistrationBean myServlet(){
    ServletRegistrationBean registrationBean new ServletRegistrationBean(new
MyServlet(),"/myServlet");
    return registrationBean;
}

 

舉個栗子:

 

 MyServlet:

public class MyServlet extends HttpServlet {

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req, resp);
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.getWriter().write("hello MyServlet");
    }
}

 

 config:

@Configuration
public class MyConfig {

    @Bean
    public ServletRegistrationBean<Servlet> myServlet(){ //是個class 直接new出來
        ServletRegistrationBean<Servlet> servletServletRegistrationBean =
                new ServletRegistrationBean<>(new MyServlet(),"/myServlet");
        return servletServletRegistrationBean;
    }
}

 

運行后:注冊成功

FilterRegistrationBean

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

 

舉個栗子:

config中加入組件:

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

 

過濾器:

public class MyFilter implements Filter {

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

    }

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

    @Override
    public void destroy() {

    }
}

 

 

請求后:

 

 

 

ServletListenerRegistrationBean

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

 

舉個栗子:

/**
 * listener 有好多的!
 */
public class MyListener implements ServletContextListener {
    @Override
    public void contextInitialized(ServletContextEvent sce) {
        System.out.println("contextInitialized...............");
    }
    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        System.out.println("contextDestroyed..................");
    }
}

組件注冊進去:

    @Bean
    public ServletListenerRegistrationBean myListener(){
        ServletListenerRegistrationBean<MyListener> registrationBean = new ServletListenerRegistrationBean<>(
                new MyListener()); //通過構造函數  s
        return registrationBean;
    }

 

啟動和退出

 

 

 

 總結:

Spring boot 幫我們自動配置Spring mvc的時候,自動注冊了前端控制器,DispatcherServlet。 (DispatcherServletAutoConfiguration類)

 這個類中有個方法:

  

@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.servletPath來修改SpringMVC前端控制器默認攔截的請求路徑
   
   registration.setName(DEFAULT_DISPATCHER_SERVLET_BEAN_NAME);
   registration.setLoadOnStartup(
         this.webMvcProperties.getServlet().getLoadOnStartup());
   if (this.multipartConfig != null) {
      registration.setMultipartConfig(this.multipartConfig);
   }
   return registration;
}

 

 

 

總結一個思路:

  經常在看源碼時候,發現定義一個接口,然后實現類是個中Factory命名的。通過某個工廠創建組件 xxFactory 是用來得到xx的!

  condition的用法,倒入哪個,那個生效。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM