How Tomcat work 之第十四章之server and services 之application

 

the application

 

这个应用程序展示了如何使用一个server和一个service。尤其是,演示了如何在StandardServer类中使用start和stop机制。这个应用中有三个类。第一个是SimpleContextConfig类,与第十三章中的应用程序的类完全相同。其他的两个类是Bootstrap和Stopper。Bootstrap类用于启动这个应用程序,Stopper类用于关闭它。

 

 

the Bootstrap Class

 

package ex14.pyrmont.startup;

import ex14.pyrmont.core.SimpleContextConfig;
import org.apache.catalina.Connector;
import org.apache.catalina.Context;
import org.apache.catalina.Engine;
import org.apache.catalina.Host;
import org.apache.catalina.Lifecycle;
import org.apache.catalina.LifecycleException;
import org.apache.catalina.LifecycleListener;
import org.apache.catalina.Loader;
import org.apache.catalina.Server;
import org.apache.catalina.Service;
import org.apache.catalina.Wrapper;
import org.apache.catalina.connector.http.HttpConnector;

import org.apache.catalina.core.StandardContext;
import org.apache.catalina.core.StandardEngine;
import org.apache.catalina.core.StandardHost;
import org.apache.catalina.core.StandardServer;
import org.apache.catalina.core.StandardService;
import org.apache.catalina.core.StandardWrapper;
import org.apache.catalina.loader.WebappLoader;

public final class Bootstrap {
  public static void main(String[] args) {
	System.setProperty("catalina.base",
		System.getProperty("user.dir"));
	Connector connector = new HttpConnector();
	Wrapper wrapper1 = new StandardWrapper();
	wrapper1.setName("Primitive");
	wrapper1.setServletClass("PrimitiveServlet");
	Wrapper wrapper2 = new StandardWrapper();
	wrapper2.setName("Modern");
	wrapper2.setServletClass("ModernServlet");
	Context context = new StandardContext();
	// StandardContext's start method adds a default mapper
	context.setPath("/app1");
	context.setDocBase("app1");
	context.addChild(wrapper1);
	context.addChild(wrapper2);
	LifecycleListener listener = new SimpleContextConfig();
	((Lifecycle) context).addLifecycleListener(listener);
	Host host = new StandardHost();
	host.addChild(context);
	host.setName("localhost");
	host.setAppBase("webapps");
	Loader loader = new WebappLoader();
	context.setLoader(loader);
	// context.addServletMapping(pattern, name);
	context.addServletMapping("/Primitive", "Primitive");
	context.addServletMapping("/Modern", "Modern");
	Engine engine = new StandardEngine();
	engine.addChild(host);
	engine.setDefaultHost("localhost");
	Service service = new StandardService();
	service.setName("Stand-alone Service");
	Server server = new StandardServer();
	server.addService(service);
	service.addConnector(connector);
	// StandardService class's setContainer method calls
	// its connectors' setContainer method
	service.setContainer(engine);
	// Start the new server
	if (server instanceof Lifecycle) {
	   try {
		server.initialize();
		((Lifecycle) server).start();
		server.await();
		// the program waits until the await method returns,
		// i.e. until a shutdown command is received.
	   }catch (LifecycleException e) {
		e.printStackTrace(System.out);
	   }
	}
 
	// Shut down the server
	if (server instanceof Lifecycle) {
	    try {		
		((Lifecycle) server).stop();	
	    }catch (LifecycleException e) {
	    	e.printStackTrace(System.out);
	    }
	}
  }
}


Bootstrap类的开始部分与第十三章的相似。创建了一个connector,两个wrapper,一个context,一个host和一个engine。之后将wrapper加到context中。然而其不将connector与顶层容器(engine)关联。main方法创建了一个Service对象,设置其名字,创建了一个server对象并添加service到server中。

 

Service service = new StandardService();
service.setName("Stand-alone Service");
Server server = new StandardServer();
server.addService(service);



main方法稍后将connector与engine添加到service中

 

service.addConnector(connector);
service.setContainer(engine);


通过添加connector给service,这个connector将与此service中的container关联。

 

main方法稍后调用server的initialize方法和start方法,从而初始化connector并启动connector与container。

 

if (server instanceof Lifecycle) {
  try {
	server.initialize();
	((Lifecycle) server).start();
      }     
}


下一步,调用server的await方法,使server等待端口为8085的关闭命令。注意现阶段连接器已经运行,并等待默认端口的请求了。

                server.await() ;

await方法直到接收到关闭命令后才会返回值。当这个发生的时候,main方法调用server的stop方法,最终停止所有的组件。

 

现在回顾一下Stopper类,停止服务。

 

the Stopper 类

             

在前面章节的应用程序中,要不是硬生生的停止或者按任一键。Stopper类提供了一种更优雅的方式来停止Catalina 服务。也保证了Lifecycle组件的stop方法都被调用。

 

package ex14.pyrmont.startup;

import java.io.OutputStream;
import java.io.IOException;
import java.net.Socket;

public class Stopper {
	public static void main(String[] args) {
	// the following code is taken from the Stop method of
	// the org.apache.catalina.startup.Catalina class
	int port = 8005;
	try {
		Socket socket = new Socket("127.0.0.1", port);
		OutputStream stream = socket.getOutputStream();
		String shutdown = "SHUTDOWN";
		for (int i = 0; i < shutdown.length(); i++)
		stream.write(shutdown.charAt(i));
		stream.flush();
		stream.close();
		socket.close();
		System.out.println("The server was successfully shut down.");
	    }
	    catch (IOException e) {
	         System.out.println("Error. The server has not been started.");
	    }
	}
}


Stopper类的main方法创建了一个Socket对象,并稍后刷新了字符串SHUTDOWN,这是当前指定端口的关闭命令。如果Catalina正在运行,它将关闭。

 

Summary

 

这一章节解释了catalian中两个重要的组件:server和service。一个server相当有用,因为它提供了一种优雅的机制来开启和停止一个Catalina部署。一个service组件封装了一个container和一个或者多个connectors。这一章节的应用显示了如何使用server和service组件。也演示了如何在StandardServer类中使用关闭机制。

 


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值