美文网首页
spring boot启动找不到ServletWebServer

spring boot启动找不到ServletWebServer

作者: 西城丶 | 来源:发表于2020-05-18 19:25 被阅读0次

    问题描述

    spring boot项目需要打包为war包,按照官网的操作:

    1. 启动类继承SpringBootServletInitializer类
    2. maven的pom文件将自带的tomcat设置为provided(这个的意思就是:被依赖项目理论上可以参与编译、测试、运行等阶段,相当于compile,但是再打包阶段做了exclude的动作)
    public class AasWebApplication extends SpringBootServletInitializer {
    
       @Override
       protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
          return application.sources(AasWebApplication.class);
       }
    
       static {
          HttpsURLConnection.setDefaultHostnameVerifier((hostname, session) -> true);
       }
    
       public static void main(String[] args){
          SpringApplication.run(AasWebApplication.class,args);
       }
    }
    
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-tomcat</artifactId>
        <scope>provided</scope>
    </dependency>
    

    在做了这两个操作之后,打包成war包是没有问题,但是本地运行spring boot项目的时候报错了,最主要的错误信息是:Unable to start ServletWebServerApplicationContext due to missing ServletWebServerFactory bean

    org.springframework.context.ApplicationContextException: Unable to start web server; nested exception is org.springframework.context.ApplicationContextException: Unable to start ServletWebServerApplicationContext due to missing ServletWebServerFactory bean.
        at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.onRefresh(ServletWebServerApplicationContext.java:155)
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:540)
        at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:140)
        at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:775)
        at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:316)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1260)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1248)
        at com.xc.AasWebApplication.main(AasWebApplication.java:33)
    Caused by: org.springframework.context.ApplicationContextException: Unable to start ServletWebServerApplicationContext due to missing ServletWebServerFactory bean.
        at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.getWebServerFactory(ServletWebServerApplicationContext.java:204)
        at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.createWebServer(ServletWebServerApplicationContext.java:178)
        at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.onRefresh(ServletWebServerApplicationContext.java:152)
        ... 8 common frames omitted
    

    问题定位

    按照错误日志,一步步debug

    private void createWebServer() {
       WebServer webServer = this.webServer;
       ServletContext servletContext = getServletContext();
       if (webServer == null && servletContext == null) {
           // 第一次会获取webServerFactory
          ServletWebServerFactory factory = getWebServerFactory();
          this.webServer = factory.getWebServer(getSelfInitializer());
       }
       else if (servletContext != null) {
          try {
             getSelfInitializer().onStartup(servletContext);
          }
          catch (ServletException ex) {
             throw new ApplicationContextException("Cannot initialize servlet context",
                   ex);
          }
       }
       initPropertySources();
    }
    
    protected ServletWebServerFactory getWebServerFactory() {
       // Use bean names so that we don't consider the hierarchy
       String[] beanNames = getBeanFactory()
             .getBeanNamesForType(ServletWebServerFactory.class);
       if (beanNames.length == 0) {
           // 错误主要是这里抛出的,也就是没有初始化ServletWebServerFactory这个类
          throw new ApplicationContextException(
                "Unable to start ServletWebServerApplicationContext due to missing "
                      + "ServletWebServerFactory bean.");
       }
       if (beanNames.length > 1) {
          throw new ApplicationContextException(
                "Unable to start ServletWebServerApplicationContext due to multiple "
                      + "ServletWebServerFactory beans : "
                      + StringUtils.arrayToCommaDelimitedString(beanNames));
       }
       return getBeanFactory().getBean(beanNames[0], ServletWebServerFactory.class);
    }
    

    具体spring boot怎么初始化tomcat的,请搜索其他资料。我们主要用到的是这个类TomcatServletWebServerFactory

    image-20200518185508165.png

    看到这边我们就大概可以定位到问题了,就是TomcatServletWebServerFactory这个类没有被初始化。

    问题解决

    所以思考下我们做了什么操作?我们将tomcat包设置了<scope>provided</scope>,我们本意是打包的时候才不需要将这个包加入lib里面,正常调试编译是可以编译到的,那么可不可能是编译器的问题呢?

    我们打开idea运行时的配置Run=>Edit configurations

    image-20200518190240842.png

    好了,看到这里,问题就知道怎么解决了,原先这个没打勾,也就是运行的时候,不会将<scope>provided</scope>的包加入编译,我们将这个打钩,重新运行一下,问题就解决了。

    这个参数跟idea版本有关系,在下面这个版本之后就被默认打钩了。

    image-20200518192028370.png

    相关文章

      网友评论

          本文标题:spring boot启动找不到ServletWebServer

          本文链接:https://www.haomeiwen.com/subject/lgupohtx.html