关于springboot:SpringBoot集成Tomcat服务

39次阅读

共计 4961 个字符,预计需要花费 13 分钟才能阅读完成。

应用的老本越低,外部封装越简单;

一、Tomcat 集成

1、依赖层级

在 SpringBoot 框架的 web 依赖包中,引入的是内嵌 Tomcat 组件,基于 SpringBoot 的版本,Tomcat 集成的是 9.0 版本;

<!-- 1、我的项目工程依赖 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <version>2.2.5.RELEASE</version>
</dependency>

<!-- 2、starter-web 依赖 -->
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-tomcat</artifactId>
  <version>2.2.5.RELEASE</version>
  <scope>compile</scope>
</dependency>

<!-- 3、starter-tomcat 依赖 -->
<dependency>
  <groupId>org.apache.tomcat.embed</groupId>
  <artifactId>tomcat-embed-core</artifactId>
  <version>9.0.31</version>
  <scope>compile</scope>
</dependency>

2、自动化配置

在 SpringBoot 框架的主动配置类中,Web 我的项目中不显式更换其余服务依赖时,默认提供了对 Tomcat 服务的治理;

@ConditionalOnWebApplication(type = Type.SERVLET)
@EnableConfigurationProperties(ServerProperties.class)
@Import({ ServletWebServerFactoryAutoConfiguration.BeanPostProcessorsRegistrar.class,
        ServletWebServerFactoryConfiguration.EmbeddedTomcat.class})
public class ServletWebServerFactoryAutoConfiguration {

    @Bean
    @ConditionalOnClass(name = "org.apache.catalina.startup.Tomcat")
    public TomcatServletWebServerFactoryCustomizer tomcatServletWebServerFactoryCustomizer(ServerProperties serverProperties) {return new TomcatServletWebServerFactoryCustomizer(serverProperties);
    }
}

二、Tomcat 架构

Server:代表整个 Tomcat 容器;

Service:服务器外部的两头组件,将一个或多个 Connector 绑定到一个 Engine 上;

Engine:示意特定服务的申请解决管道,接管 Connector 的申请并响应;

Host:网络主机名称;

Connector:连接器解决与客户端的通信;

Context:代表一个 Web 应用程序的上下文;

参考 Tomcat9.0 版本的外围组件形容,对于框架有大抵的理解后,再去剖析集成原理,会更容易把握主线逻辑;

三、Tomcat 配置

1、根底配置

在配置文件中,对 Tomcat 做一些基础性的设置,查看上面的配置类能够晓得,这些属性存在默认值;

server:
  port: 8082                # 端口号
  tomcat:                   # Tomcat 组件
    uri-encoding: UTF-8     # URI 编码
    max-threads: 100        # 最大工作线程
    min-spare-threads: 10   # 最小工作线程 

2、属性配置类

在服务配置中,提供多种服务器的适配,像 Tomcat、Jetty、Netty、Undertow,从策略上看,配置分为公共属性以及各种服务器的适配属性;

更多配置信息,能够参考残缺的源码和正文阐明;

@ConfigurationProperties(prefix = "server", ignoreUnknownFields = true)
public class ServerProperties {
    private Integer port;
    public static class Tomcat {
        private Charset uriEncoding = StandardCharsets.UTF_8;
        private int maxThreads = 200;
        private int minSpareThreads = 10;
    }
}

3、配置加载剖析

  • 基于配置的属性,定制化治理 Tomcat 服务的信息;
public class TomcatWebServerFactoryCustomizer
        implements WebServerFactoryCustomizer<ConfigurableTomcatWebServerFactory> {
    @Override
    public void customize(ConfigurableTomcatWebServerFactory factory) {
        ServerProperties properties = this.serverProperties;
        ServerProperties.Tomcat tomcatProperties = properties.getTomcat();
        PropertyMapper propertyMapper = PropertyMapper.get();
        customizeStaticResources(factory);
    }
}
  • TomcatWeb 服务工厂,这里在创立 WebServer 时,应用的是 Tomcat,须要适当的理解一下 Tomcat 架构;
public class TomcatServletWebServerFactory extends AbstractServletWebServerFactory
        implements ConfigurableTomcatWebServerFactory, ResourceLoaderAware {
    @Override
    public WebServer getWebServer(ServletContextInitializer... initializers) {Tomcat tomcat = new Tomcat();
        Connector connector = new Connector(this.protocol);
        connector.setThrowOnFailure(true);
        tomcat.getService().addConnector(connector);
        customizeConnector(connector);
        tomcat.setConnector(connector);
        tomcat.getHost().setAutoDeploy(false);
        configureEngine(tomcat.getEngine());
        prepareContext(tomcat.getHost(), initializers);
        return getTomcatWebServer(tomcat);
    }
}

四、周期治理办法

1、管制类

  • WebServer 的简略接口,只申明端口获取,服务启动和进行相干办法;
public interface WebServer {

    // 获取监听的端口
    int getPort();
    
    // 服务启动
    void start() throws WebServerException;

    // 服务进行
    void stop() throws WebServerException;}
  • SpringBoot 中,Tomcat 服务外围管制类,通过 TomcatServletWebServerFactory 工厂类创立,对 Tomcat 生命周期的治理提供了一层包装;
public class TomcatWebServer implements WebServer {

    private final Tomcat tomcat;

    private final Map<Service, Connector[]> serviceConnectors = new HashMap<>();
}
  • Apache 组件中,轻量级 Tomcat 启动器,提供了 Tomcat 根底配置,比方默认的 Port 和 HostName,以及生命周期治理的办法,TomcatWebServer 类中调用的就是该 API 中的具体方法;
public class Tomcat {

    protected Server server;
    protected int port = 8080;
    protected String hostname = "localhost";
    
    // 初始化服务
    public void init() throws LifecycleException {getServer();
        server.init();}
    
    // 启动服务
    public void start() throws LifecycleException {getServer();
        server.start();}

    // 进行服务
    public void stop() throws LifecycleException {getServer();
        server.stop();}
}

2、外围办法

2.1 初始化 ,初始化时,调用 Apache-Tomcat 类中启动办法;

public class TomcatWebServer implements WebServer {
    /**
     * 初始化办法
     */
    private void initialize() throws WebServerException {
        // 控制台日志
        logger.info("Tomcat initialized with port(s):" + getPortsDescription(false));
        synchronized (this.monitor) {
            // 调用 Apache-Tomcat 类中启动办法
            this.tomcat.start();}
    }
}

2.2 启动 ,在初始化的办法中,调用的 Tomcat 启动办法,这里对状态进行校验并输入日志;

public class TomcatWebServer implements WebServer {
    /**
     * 启动办法
     */
    public void start() throws WebServerException {synchronized (this.monitor) {if (this.started) {return;}
            checkThatConnectorsHaveStarted();
            // 启动状态的标识
            this.started = true;
            // 控制台日志
            logger.info("Tomcat started on port(s):" + getPortsDescription(true) + "with context path'"
                    + getContextPath() + "'");
        }
    }
}

2.3 进行 ,在组件生命周期的惯例治理逻辑中,进行服务之后进行销毁动作的执行,其中天然波及到多个状态标识的转换;

public class TomcatWebServer implements WebServer {
    /**
     * 进行办法
     */
    public void stop() throws WebServerException {synchronized (this.monitor) {
            // 状态变动
            boolean wasStarted = this.started;
            this.started = false;
            // Tomcat 服务进行
            stopTomcat();
            this.tomcat.destroy();}
    }
}

五、参考源码

 编程文档:https://gitee.com/cicadasmile/butte-java-note

利用仓库:https://gitee.com/cicadasmile/butte-flyer-parent

正文完
 0