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 ...
随机推荐
- (二)、Python 基础
Python入门 一.第一句Python 在 /home/dev/ 目录下创建 hello.py 文件,内容如下: print "hello,world" 执行 hello.py ...
- python版opencv:如何用笔记本摄像头拍照保存
因为需要制作制作数据集 所以需要在笔记本上外置了一个logi的摄像头 准备使用python上得opencv来进行拍照 环境:opencv+pycharm+win10+py3 #coding:utf-8 ...
- ./vi: line 2: mkdir: command not found
当前两天博主在写脚本的时候,运行脚本时候总是出现此消息,很郁闷, 开始我以为可能是我mkdir的函数库依赖的问题,但是当我用其他的脚本创建 目录的时候,命令又可以用了,找了半天,终于找到了答案 --- ...
- Codeforces Round #438 C - Qualification Rounds 思维
C. Qualification Rounds time limit per test 2 seconds memory limit per test 256 megabytes input stan ...
- HDU 5293 Tree chain problem 树形DP
题意: 给出一棵\(n\)个节点的树和\(m\)条链,每条链有一个权值. 从中选出若干条链,两两不相交,并且使得权值之和最大. 分析: 题解 #include <cstdio> #incl ...
- python里面list()函数
1. list() 方法用于将元组转换为列表. 元组与列表是非常类似的,区别在于元组的元素值不能修改,元组是放在括号中,列表是放于方括号中. 2. python里面的变量不用提前声明.
- PowerShell技巧:使用XPath语法查询XML文件
[TechTarget中国原创] XML是存储结构化数据的一个很好的途径,但是想要让数据在其中发挥作用又会有些困难.每一种语言都有其特定方式来查询XML文件中的命名空间.元素及属性.PowerShel ...
- erlang中的原子(atom)内部实现[转]
转自: http://www.kongqingquan.com/archives/208#more-208 Erlang中的atom由通用hash表实现,虚拟机中atom最终的用数值表示,对应表中的下 ...
- Mongoid Paging and Iterating Over Large Collections
遍历数据库中的所有记录时,我们首先想到的是Model.all.each.但是,当数据量很大的时候(数万?),这就不怎么合适了,因为Model.all.each会一次性加载所有记录,并将其实例化成 Mo ...
- 《Cracking the Coding Interview》——第17章:普通题——题目8
2014-04-28 23:35 题目:最大子数组和问题. 解法:O(n)解法. 代码: // 17.8 Find the consecutive subarray with maximum sum ...