SpringBoot学习笔记(八)SpringBoot_Web开发四

一、配置嵌入式Servlet容器

SpringBoot默认使用的是嵌入式的Servlet容器(Tomcat)
使用嵌入式的Servlet容器,那我们可以考虑几个问题

  • 1.如何定制和修改Servlet容器的相关配置(使用外置的话,可以从配置文件里改,内置的该从哪改呢?)
    答:
    1).在配置文件(application.properties / application.yaml)里修改与server相关的配置(ServerProperties),这种属于通用的Servlet容器设置
    server.port=8081 修改端口号
    2).编写一个定制器
    参考:https://blog.csdn.net/l1336037686/article/details/81047312
  • 2.SpringBoot能不能支持其他的Servlet容器

二、注册Servlet三大组件(Servlet、Filter、Listener)

SpringBoto创建的项目默认是以jar的方式启动默认的Tomcat,这不是一个标准的web项目
因为标准web项目会有一个webapp文件夹,在webapp/WEB-INF/pom.xml文件夹里注册这三个组件
没有这一文件夹我们可以利用ServletRegistrationBeanFilterRegistrationBeanServletListenerRegistrationBean完成注册
对这些组件的相关设置也可以直接在方法里面设置
MyServerConfig .java

@Configuration
public class MyServerConfig {
    @Bean //把他加在容器中,一定要做
    public ServletRegistrationBean myServlet(){
        //注册三大组件
        ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(new MyServlet(),"/myServlet");
        return servletRegistrationBean;
    }
}

MyServlet.java

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

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
       resp.getWriter().write("Hello!MyServlet");
    }
}
效果

其他两个类似
MyServerConfig.java

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

MyServerConfig.java

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

SpringBoot帮我们自动SpringMVC的时候,自动的注册SpringMVC的前端控制器;
DispatcherServletAutoConfiguration中:

     protected static class DispatcherServletRegistrationConfiguration {
        private final WebMvcProperties webMvcProperties;
        private final MultipartConfigElement multipartConfig;

        public DispatcherServletRegistrationConfiguration(WebMvcProperties webMvcProperties, ObjectProvider multipartConfigProvider) {
            this.webMvcProperties = webMvcProperties;
            this.multipartConfig = (MultipartConfigElement)multipartConfigProvider.getIfAvailable();
        }

        @Bean(
            name = {"dispatcherServletRegistration"}
        )
        @ConditionalOnBean(
            value = {DispatcherServlet.class},
            name = {"dispatcherServlet"}
        )
        public DispatcherServletRegistrationBean dispatcherServletRegistration(DispatcherServlet dispatcherServlet) {
            DispatcherServletRegistrationBean registration = new DispatcherServletRegistrationBean(dispatcherServlet, this.webMvcProperties.getServlet().getPath());
 //默认拦截: /  所有请求;包静态资源,但是不拦截jsp请求;   /*会拦截jsp
 //可以通过server.servletPath来修改SpringMVC前端控制器默认拦截的请求路径
            registration.setName("dispatcherServlet");
            registration.setLoadOnStartup(this.webMvcProperties.getServlet().getLoadOnStartup());
            if (this.multipartConfig != null) {
                registration.setMultipartConfig(this.multipartConfig);
            }

            return registration;
        }
    }

三、切换其他嵌入式Servlet容器(Jetty、Undertow)

Jetty,适合用于开发长连接的应用,如聊天
Undertow,不支持jsp,但是它的并发性能非常好
Tomcat(默认使用)默认使用的原因:


   org.springframework.boot
   spring-boot-starter-web
   引入web模块默认就是使用嵌入式的Tomcat作为Servlet容器;

改为Jetty



   org.springframework.boot
   spring-boot-starter-web
   
      
         spring-boot-starter-tomcat
         org.springframework.boot
      
   




   spring-boot-starter-jetty
   org.springframework.boot

改为Undertow



   org.springframework.boot
   spring-boot-starter-web
   
      
         spring-boot-starter-tomcat
         org.springframework.boot
      
   




   spring-boot-starter-undertow
   org.springframework.boot

四、嵌入式Servlet容器自动配置原理

为何通过修改dependency就能修改Servlet容器?--- 探索源码
根据引入的依赖,去判断使用哪个Servlet容器

@Configuration
@ConditionalOnWebApplication
@EnableConfigurationProperties({ServerProperties.class})
public class EmbeddedWebServerFactoryCustomizerAutoConfiguration {
    public EmbeddedWebServerFactoryCustomizerAutoConfiguration() {
    }
    @Configuration
    @ConditionalOnClass({Undertow.class, SslClientAuthMode.class})
    public static class UndertowWebServerFactoryCustomizerConfiguration {
        public UndertowWebServerFactoryCustomizerConfiguration() {
        }

        @Bean
        public UndertowWebServerFactoryCustomizer undertowWebServerFactoryCustomizer(Environment environment, ServerProperties serverProperties) {
            return new UndertowWebServerFactoryCustomizer(environment, serverProperties);
        }
    }

    @Configuration
    @ConditionalOnClass({Server.class, Loader.class, WebAppContext.class})
    public static class JettyWebServerFactoryCustomizerConfiguration {
        public JettyWebServerFactoryCustomizerConfiguration() {
        }

        @Bean
        public JettyWebServerFactoryCustomizer jettyWebServerFactoryCustomizer(Environment environment, ServerProperties serverProperties) {
            return new JettyWebServerFactoryCustomizer(environment, serverProperties);
        }
    }

    @Configuration
    @ConditionalOnClass({Tomcat.class, UpgradeProtocol.class})//判断当前是否引入Tomcat依赖
    public static class TomcatWebServerFactoryCustomizerConfiguration {
        public TomcatWebServerFactoryCustomizerConfiguration() {
        }

        @Bean
        public TomcatWebServerFactoryCustomizer tomcatWebServerFactoryCustomizer(Environment environment, ServerProperties serverProperties) {
            return new TomcatWebServerFactoryCustomizer(environment, serverProperties);
        }
    }
...
}

那么,我们修改容器的配置是怎么生效的?
修改容器有两种方式:

  • 1)在配置文件中修改相关属性,它与serverProperties绑定
  • 2)通过定制器ConfigurableServletWebServerFactory
    定义一些属性的设置方法


public interface ConfigurableWebServerFactory extends WebServerFactory, ErrorPageRegistry {
    void setPort(int port);

    void setAddress(InetAddress address);

    void setErrorPages(Set errorPages);

    void setSsl(Ssl ssl);

    void setSslStoreProvider(SslStoreProvider sslStoreProvider);

    void setHttp2(Http2 http2);

    void setCompression(Compression compression);

    void setServerHeader(String serverHeader);
}

五、嵌入式Servlet容器启动原理

什么时候创建嵌入式的Servlet容器工厂?
什么时候获取嵌入式的Servlet容器并启动Tomcat?

六、使用外部Servlet容器&JSP支持

七、外部Servlet容器启动SpringBoot应用原理

你可能感兴趣的:(SpringBoot学习笔记(八)SpringBoot_Web开发四)