Tomcat学习笔记(十三)
服务器组件和服务组件
服务器组件
org.apache.catalina.Server接口的实例表示Catalina的整个servlet引擎,包含了所有的组件。使用一种优雅的方法来启动/关闭整个系统,不需要再对连接器和容器分别启动/关闭。
关闭/启动的工作原理。当启动服务器组件时,他会启动其中所有的组件,然后它就一直等待关闭命令,如果要关闭系统,可以向指定端口发送一条关闭命令。服务器收到关闭命令后,就会关闭其中所有的组件。
看一下Server接口的几个方法。
public interface Server extends Lifecycle {
public int getPort();//返回监听关闭的端口
public void setPort(int port);//设置关闭端口
public Catalina getCatalina();//返回catalina组件
public void addService(Service service);//添加服务
public Service findService(String name);//查询服务
public Service[] findServices();//查询所有服务
public void removeService(Service service);//移除服务
}
StandardServer类
StandardServer类是Server接口的标准实现。
一个服务器组件可以有0个或者多个服务组件。StandardServer类提供了addService()方法、removeService()方法和findService方法的实现。
addService将服务组件添加到服务器组件中,服务器组件中包含一个数组来保存服务组件。
public void addService(Service service) {
service.setServer(this);
synchronized (services) {
Service results[] = new Service[services.length + 1];
System.arraycopy(services, 0, results, 0, services.length);
results[services.length] = service;
services = results;
if (getState().isAvailable()) { //服务可用,就启动服务
try {
service.start();
} catch (LifecycleException e) {
// Ignore
}
}
// Report this property change to interested listeners
support.firePropertyChange("service", null, service);
}
}
removeService从服务组件数组中移除,并停止服务。
public void removeService(Service service) {
synchronized (services) {
int j = -1;
for (int i = 0; i < services.length; i++) {
if (service == services[i]) {
j = i;
break;
}
}
if (j < 0)
return;
try {
services[j].stop();
} catch (LifecycleException e) {
// Ignore
}
int k = 0;
Service results[] = new Service[services.length - 1];
for (int i = 0; i < services.length; i++) {
if (i != j)
results[k++] = services[i];
}
services = results;
// Report this property change to interested listeners
support.firePropertyChange("service", service, null);
}
}
StandardServer类的4个生命周期相关的方法,是由LifecycleBase中的init调用initInternal(StandardServer),start调用startInternal(StandardServer),stop调用stopInternal(StandardServer),await(StandardServer)方法。
initInternal主要是对资源的初始化和服务组件的初始化。
protected void initInternal() throws LifecycleException {
super.initInternal();
...
// Register the naming resources
globalNamingResources.init();
...
// Initialize our defined Services
for (int i = 0; i < services.length; i++) {
services[i].init();
}
}
startInternal设置生命周期,设置服务器组件的状态,启动服务组件。
@Override
protected void startInternal() throws LifecycleException {
fireLifecycleEvent(CONFIGURE_START_EVENT, null);
setState(LifecycleState.STARTING);
globalNamingResources.start();
// Start our defined Services
synchronized (services) {
for (int i = 0; i < services.length; i++) {
services[i].start();
}
}
}
await一直等待停止命令。
Service接口
主要与连接器,服务器组件,执行器相关的信息
public interface Service extends Lifecycle {
public void addConnector(Connector connector);
public Connector[] findConnectors();
public void removeConnector(Connector connector);
public void addExecutor(Executor ex);
public Executor[] findExecutors();
public Executor getExecutor(String name);
public void removeExecutor(Executor ex);
public Server getServer();
public void setServer(Server server);
}
ServiceStandard对Service的接口实现,同时也有生命周期方法
startInternal
protected void startInternal() throws LifecycleException {
if(log.isInfoEnabled())
log.info(sm.getString("standardService.start.name", this.name));
setState(LifecycleState.STARTING);
// Start our defined Container first
if (container != null) {
synchronized (container) {
container.start();
}
}
synchronized (executors) {
for (Executor executor: executors) {
executor.start();
}
}
// Start our defined Connectors second
synchronized (connectors) {
for (Connector connector: connectors) {
try {
// If it has already failed, don't try and start it
if (connector.getState() != LifecycleState.FAILED) {
connector.start();
}
} catch (Exception e) {
log.error(sm.getString(
"standardService.connector.startFailed",
connector), e);
}
}
}
}
initInternal初始化容器,执行器以及连接器。
protected void initInternal() throws LifecycleException {
super.initInternal();
if (container != null) {
container.init();
}
// Initialize any Executors
for (Executor executor : findExecutors()) {
if (executor instanceof LifecycleMBeanBase) {
((LifecycleMBeanBase) executor).setDomain(getDomain());
}
executor.init();
}
// Initialize our defined Connectors
synchronized (connectors) {
for (Connector connector : connectors) {
try {
connector.init();
} catch (Exception e) {
String message = sm.getString(
"standardService.connector.initFailed", connector);
log.error(message, e);
if (Boolean.getBoolean("org.apache.catalina.startup.EXIT_ON_INIT_FAILURE"))
throw new LifecycleException(message);
}
}
}
}
stopInternal停止连接器和执行器。
protected void stopInternal() throws LifecycleException {
// Pause connectors first
synchronized (connectors) {
for (Connector connector: connectors) {
try {
connector.pause();
} catch (Exception e) {
log.error(sm.getString(
"standardService.connector.pauseFailed",
connector), e);
}
}
}
if(log.isInfoEnabled())
log.info(sm.getString("standardService.stop.name", this.name));
setState(LifecycleState.STOPPING);
// Stop our defined Container second
if (container != null) {
synchronized (container) {
container.stop();
}
}
// Now stop the connectors
synchronized (connectors) {
for (Connector connector: connectors) {
if (!LifecycleState.STARTED.equals(
connector.getState())) {
// Connectors only need stopping if they are currently
// started. They may have failed to start or may have been
// stopped (e.g. via a JMX call)
continue;
}
try {
connector.stop();
} catch (Exception e) {
log.error(sm.getString(
"standardService.connector.stopFailed",
connector), e);
}
}
}
synchronized (executors) {
for (Executor executor: executors) {
executor.stop();
}
}
}
Tomcat学习笔记(十三)的更多相关文章
- python3.4学习笔记(十三) 网络爬虫实例代码,使用pyspider抓取多牛投资吧里面的文章信息,抓取政府网新闻内容
python3.4学习笔记(十三) 网络爬虫实例代码,使用pyspider抓取多牛投资吧里面的文章信息PySpider:一个国人编写的强大的网络爬虫系统并带有强大的WebUI,采用Python语言编写 ...
- java之jvm学习笔记十三(jvm基本结构)
java之jvm学习笔记十三(jvm基本结构) 这一节,主要来学习jvm的基本结构,也就是概述.说是概述,内容很多,而且概念量也很大,不过关于概念方面,你不用担心,我完全有信心,让概念在你的脑子里变成 ...
- Go语言学习笔记十三: Map集合
Go语言学习笔记十三: Map集合 Map在每种语言中基本都有,Java中是属于集合类Map,其包括HashMap, TreeMap等.而Python语言直接就属于一种类型,写法上比Java还简单. ...
- Vue学习笔记十三:Vue+Bootstrap+vue-resource从接口获取数据库数据
目录 前言 SpringBoot提供后端接口 Entity类 JPA操作接口 配置文件 数据库表自动映射,添加数据 写提供数据的接口 跨域问题 前端修改 效果图 待续 前言 Vue学习笔记九的列表案例 ...
- java jvm学习笔记十三(jvm基本结构)
欢迎装载请说明出处:http://blog.csdn.net/yfqnihao 这一节,主要来学习jvm的基本结构,也就是概述.说是概述,内容很多,而且概念量也很大,不过关于概念方面,你不用担心,我完 ...
- Tomcat 学习笔记二
学习一 java.bean.PropertyChangeListener用来监听bean类的属性值改变.当改变时同时执行对应事件.而且是线程安全的.tomcat用此reload的Boolean值改变是 ...
- Tomcat ----> 学习笔记
源码之几个常见类和接口的关系 在学习Servlet的时候经常见到以下几个合成单词和非合成单词:Servlet.GenericServlet.HttpServlet.它们之间有联系的.接下来我把它们的联 ...
- Tomcat学习笔记【1】--- WEB服务器、JavaEE、Tomcat背景、Tomcat版本
本文主要讲学习Tomcat需要知道的基础知识. 一 Web服务器 1.1 简介 Web服务器可以解析HTTP协议.当Web服务器接收到一个HTTP请求,会返回一个HTTP响应,例如送回一个HTML页面 ...
- python 学习笔记十三 JQuery(进阶篇)
jQuery 是一个 JavaScript 库. jQuery 极大地简化了 JavaScript 编程. 安装jQuery 有两个版本的 jQuery 可供下载: Production versio ...
随机推荐
- Go Doc文档
Go为我们提供了快速生成文档和查看文档的工具,很容易编写查看代码文档.在项目协作过程中,可以帮助我们快速理解代码. 查看文档方式有两种:一种是通过终端查看,使用go doc命令,一种是通过网页查看,使 ...
- shell 脚本入门
shell script 是一个程序化脚本,使用shell语法跟linux命令完成的一个程序. 注意事项: 文件开头: #!/bin/bash 文本以enter符号作为开始执行该行语句,用跳脱符 \e ...
- 多线程(threading module)
一.线程与进程 线程定义:线程是操作系统能够进行运算调度的最小单位.它被包含在进程之中,是进程中的实际运作单位.一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不 ...
- 微信小程序推广方案
拥有小程序只是基础,能玩转小程序运营才是关键.本文将会简单讲述十种最实用的小程序推广策略,结合具体案例阐述商家企业如何在拥有小程序后玩转小程序,快速实现小程序的推广. 一. 公众号+小程序 小程序可以 ...
- C语言结构体指针成员强制类型转换
#include <stdio.h> #include <stdlib.h> typedef struct ListElmt_ { void *data; struct Lis ...
- Python全栈day 01
Python全栈day 01 一.计算机认识 用户 软件,类似微信.QQ.游戏等应用程序,由程序员编写,在系统中运行,完成各种活动,方便人们使用. 操作系统,主要分为windows系统.Linux系统 ...
- 笔记-python-多环境-virtualenv
笔记-python-多环境-virtualenv 1. 多环境 在开发Python应用程序的时候,系统安装的Python3只有一个版本:3.6.4,所有第三方的包都会被pip安装到Pytho ...
- 笔记-scrapy-去重
笔记-scrapy-去重 1. scrapy 去重 scrapy 版本:1.5.0 第一步是要找到去重的代码,scrapy在请求入列前去重,具体源码在scheduler.py: def en ...
- 【文件处理】RandomAccessFile
一,RandomAccessFile的用途: 使用RandomAccessFile的最大好处在于,一般的InputStream和OutputStream类对于文件都是顺序读取的,不能跳跃读取数据.而R ...
- Mac下安装Angular报错处理
安装 Angular CLI 命令: sudo npm install -g @angular/cli 打印如下错误:(权限问题) gyp WARN EACCES user "root&qu ...