How Tomcat Works学习笔记<十三>
来源:互联网 发布:unity3d api 编辑:程序博客网 时间:2024/04/27 16:35
Server和Service
在前面的章节中Catalina已经有了连接器(Connector)和容器(Container),但是还缺少一种好的启动和停止Servlet容器的机制,Server和Service能很好的解决这个问题。
Server
org.apache.catalina.Server接口表示完整的Servlet容器和相关的其他组件,提供了优雅启动和停止整个系统的机制,有了它以后没有必要再分别去启动连接器和容器。
当你启动一个Server的时候,它会启动在其内的所有组件,然后等待识别的shutdown命令,一旦通过指定的端口发送了shutdown命令,被server接收到以后它将停止所有的组件,Server定义如下:
public interface Server {
public String getInfo();
public NamingResources getGlobalNamingResources();
public void setGlobalNamingResources(NamingResources globalNamingResources);
public int getPort();
public void setPort(int port);
public String getShutdown();
public void setShutdown(String shutdown);
public void addService(Service service);
public void await();
public Service findService(String name);
public Service[] findServices();
public void removeService(Service service);
public void initialize()throws LifecycleException;
}
通过addService方法可以下Server添加Service对象。
StandardServer
StandardServer是Server接口的标准实现,其中最重要的是他的shutdown机制,同时也包括一些解析Server配置(server.xml)的方法。
一个Server包括一个或多个Service,提供了addService和removeService方法,作为组件,Server也实现了生命周期的相关功能,提供了initialize、start、stop和await方法。
initialize方法
initialize方法会初始化Service并添加到Server实例当中:
public void initialize()throws LifecycleException {
if (initialized)
throw new LifecycleException (
sm.getString("standardServer.initialize.initialized"));
initialized = true;
// Initialize our defined Services
for (int i = 0; i < services.length; i++) {
services[i].initialize();
}
}
在StandardServer中增加了initialized变量,防止重复初始化Server。
start方法
start方法会启动所有的Service,从而启动其它组件,像连接器、容器等:
public void start() throws LifecycleException {
// Validate and update our current component state
if (started)
throw new LifecycleException
(sm.getString("standardServer.start.started"));
// Notify our interested LifecycleListeners
lifecycle.fireLifecycleEvent(BEFORE_START_EVENT,null);
lifecycle.fireLifecycleEvent(START_EVENT, null);
started = true;
// Start our defined Services
synchronized (services) {
for (int i = 0; i < services.length; i++) {
if (services[i] instanceof Lifecycle)
((Lifecycle) services[i]).start();
}
}
// Notify our interested LifecycleListeners
lifecycle.fireLifecycleEvent(AFTER_START_EVENT, null);
}
在StandardServer中添加了started变量控制重复调用start方法。
stop方法
stop方法停止server:
public void stop() throws LifecycleException {
// Validate and update our current component state
if (!started)
throw new LifecycleException
(sm.getString("standardServer.stop.notStarted"));
// Notify our interested LifecycleListeners
lifecycle.fireLifecycleEvent(BEFORE_STOP_EVENT, null);
lifecycle.fireLifecycleEvent(STOP_EVENT, null);
started = false;
// Stop our defined Services
for (int i = 0; i < services.length; i++) {
if (services[i] instanceof Lifecycle)
((Lifecycle) services[i]).stop();
}
// Notify our interested LifecycleListeners
lifecycle.fireLifecycleEvent(AFTER_STOP_EVENT, null);
}
stop方法会停止所有service,并把started改为false,从而可以再次启动Server。
await方法
await方法的职责是停止整个Tomcat部署:
public void await() {
// Set up a server socket to wait on
ServerSocket serverSocket = null;
try {
serverSocket =
new ServerSocket(port, 1,
InetAddress.getByName("127.0.0.1"));
} catch (IOException e) {
System.err.println("StandardServer.await: create[" + port
+ "]: " + e);
e.printStackTrace();
System.exit(1);
}
// Loop waiting for a connection and a valid command
while (true) {
// Wait for the next connection
Socket socket = null;
InputStream stream = null;
try {
socket = serverSocket.accept();
socket.setSoTimeout(10 * 1000); // Ten seconds
stream = socket.getInputStream();
} catch (AccessControlException ace) {
System.err.println("StandardServer.accept security exception: "+ ace.getMessage());
continue;
} catch (IOException e) {
System.err.println("StandardServer.await: accept: " + e);
e.printStackTrace();
System.exit(1);
}
// Read a set of characters from the socket
StringBuffer command = new StringBuffer();
int expected = 1024; // Cut off to avoid DoS attack
while (expected < shutdown.length()) {
if (random == null)
random = new Random(System.currentTimeMillis());
expected += (random.nextInt() % 1024);
}
while (expected > 0) {
int ch = -1;
try {
ch = stream.read();
} catch (IOException e) {
System.err.println("StandardServer.await: read: " + e);
e.printStackTrace();
ch = -1;
}
if (ch < 32) // Control character or EOF terminates loop
break;
command.append((char) ch);
expected--;
}
// Close the socket now that we are done with it
try {
socket.close();
} catch (IOException e) {
;
}
// Match against our command string
boolean match = command.toString().equals(shutdown);
if (match) {
break;
} else
System.err.println("StandardServer.await: Invalid command '" +
command.toString() + "' received");
}
// Close the server socket and return
try {
serverSocket.close();
} catch (IOException e) {
;
}
}
await方法会监听来自客户端的命令,一旦发现传来shutdown的命令,将会停止这个Tomcat部署。
Service
org.apache.catalina.Service接口表示一个服务,一个服务可以包括一个容器和多个连接器,所有的连接器都必须分配给容器,Service接口定义如下:
public interface Service {
public Container getContainer();
public void setContainer(Container container);
public String getInfo();
public String getName();
public void setName(String name);
public Server getServer();
public void setServer(Server server);
public void addConnector(Connector connector);
public Connector[] findConnectors();
public void removeConnector(Connector connector);
public void initialize()throws LifecycleException;
}
StandardService
StandardService是Service的标准实现类,包括两种类型的组件:连接器和容器
通过setContainer方法为Service分配容器:
public void setContainer(Container container) {
Container oldContainer = this.container;
if ((oldContainer != null) && (oldContainerinstanceof Engine))
((Engine) oldContainer).setService(null);
this.container = container;
if ((this.container != null) && (this.container instanceof Engine))
((Engine) this.container).setService(this);
if (started && (this.container !=null) &&
(this.container instanceof Lifecycle)) {
try {
((Lifecycle) this.container).start();
} catch (LifecycleException e) {
;
}
}
synchronized (connectors) {
for (int i = 0; i < connectors.length; i++)
connectors[i].setContainer(this.container);
}
if (started && (oldContainer != null) &&
(oldContainer instanceof Lifecycle)) {
try {
((Lifecycle) oldContainer).stop();
} catch (LifecycleException e) {
;
}
}
// Report this property change to interested listeners
support.firePropertyChange("container", oldContainer, this.container);
}
通过addConnector方法添加连接器:
public void addConnector(Connector connector) {
synchronized (connectors) {
connector.setContainer(this.container);
connector.setService(this);
Connector results[] = new Connector[connectors.length + 1];
System.arraycopy(connectors, 0, results, 0, connectors.length);
results[connectors.length] = connector;
connectors = results;
if (initialized) {
try {
connector.initialize();
} catch (LifecycleException e) {
e.printStackTrace(System.err);
}
}
if (started && (connector instanceof Lifecycle)) {
try {
((Lifecycle) connector).start();
} catch (LifecycleException e) {
;
}
}
// Report this property change to interested listeners
support.firePropertyChange("connector", null, connector);
}
}
通过removeConnector方法移除连接器:
public void removeConnector(Connector connector) {
synchronized (connectors) {
int j = -1;
for (int i = 0; i < connectors.length; i++) {
if (connector == connectors[i]) {
j = i;
break;
}
}
if (j < 0)
return;
if (started && (connectors[j] instanceof Lifecycle)) {
try {
((Lifecycle) connectors[j]).stop();
} catch (LifecycleException e) {
;
}
}
connectors[j].setContainer(null);
connector.setService(null);
int k = 0;
Connector results[] = new Connector[connectors.length - 1];
for (int i = 0; i < connectors.length; i++) {
if (i != j)
results[k++] = connectors[i];
}
connectors = results;
// Report this property change to interested listeners
support.firePropertyChange("connector", connector, null);
}
}
- How Tomcat Works学习笔记<十三>
- How Tomcat works学习笔记<零.序>
- How Tomcat Works学习笔记<一>
- How Tomcat works学习笔记<二>
- How Tomcat works学习笔记<三>
- How Tomcat Works学习笔记<四>
- How Tomcat Works学习笔记<五>
- How Tomcat Works学习笔记<六>
- How Tomcat Works学习笔记<七>
- How Tomcat Works学习笔记<八>
- How Tomcat Works学习笔记<九>
- How Tomcat Works学习笔记<十>
- How Tomcat Works学习笔记<十一>
- How Tomcat Works学习笔记<十二>
- How Tomcat Works学习笔记<十四>
- How Tomcat Works学习笔记<十五>
- 《How Tomcat Works》学习笔记(一)
- 《How Tomcat Works》学习笔记(二)
- 可变参数的函数应用
- 构造链表ABC,删除在A中的ABC的公共元素_C++实现
- hibernate和MySQL乱码问题
- linux oracle定时备份
- calculate distance within matlab
- How Tomcat Works学习笔记<十三>
- UBUNTU下利用net-snmp进行GTK编程
- 大四的学生
- sgu326 Perspective(最大流)
- ubuntu第一次使用root设置密码
- 构造双向链表根据访问频度动态调整位置_C++实现
- 我的第一个汇编程序,led流水灯
- 正则表达式:切割“\.”
- 获取Repeater, DataList, Gridview中的索引号(行号,序号)