标签:
Service service = new StandardService(); service.setName("Stand-alone Service"); Server server = new StandardServer(); server.addService(service);
package org.apache.catalina; import org.apache.catalina.deploy.NamingResources; 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; }
A1)shutdown属性:保存了必须发送给Server 实例用来关闭整个系统的关闭命令;A2)port属性:定义了服务器组件会从哪个端口获取关闭命令;A3)addService() 和 removeService()方法:为服务器组件添加或移除服务组件;A4)findService()方法:返回添加到该服务器组件中的所有服务组件;A5)initialize()方法:包含在系统启动前要执行的一些代码;
public void initialize() throws LifecycleException { //org.apache.catalina.StandardServer.initialize(). 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(); } }
public void start() throws LifecycleException { //org.apache.catalina.StandardServer.start(). // 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); }
public void stop() throws LifecycleException { //org.apache.catalina.StandardServer.stop(). // 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); }
public void await() { //org.apache.catalina.StandardServer.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(); //highlight line. 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); //highlight line. 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) { ; } }
step1)创建一个ServerSocket对象,监听8085端口,并在while循环中调用它的accept()方法;step2)当在指定端口上接收到消息时,accept()方法才会返回;step3)将接收到的消息与关闭命令的字符串相比较,相同的话就跳出while循环,关闭 ServerSocket,否则会再次循环,继续等待消息;
package org.apache.catalina; 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; }
1)StandardService.initialize()方法:用于初始化添加到其中的所有连接器;2)StandardService.start()方法:启动连接器和所有servlet容器;
private Connector connectors[] = new Connector[0]; // defined in StandardService.
public void setContainer(Container container) { // org.apache.catalina.core.StandardService.setContainer(). Container oldContainer = this.container; if ((oldContainer != null) && (oldContainer instanceof 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); }
public void addConnector(Connector connector) { //org.apache.catalina.core.StandardService.addConnector(). 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(); //highlight line. } catch (LifecycleException e) { e.printStackTrace(System.err); } } if (started && (connector instanceof Lifecycle)) { try { ((Lifecycle) connector).start();//highlight line. } catch (LifecycleException e) { ; } } // Report this property change to interested listeners support.firePropertyChange("connector", null, connector); } } public void removeConnector(Connector connector) { //org.apache.catalina.core.StandardService.removeConnector(). 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); } }
public void initialize() throws LifecycleException { //org.apache.catalina.core.StandardService.initialize(). if (initialized) throw new LifecycleException ( sm.getString("standardService.initialize.initialized")); initialized = true; // Initialize our defined Connectors synchronized (connectors) { for (int i = 0; i < connectors.length; i++) { connectors[i].initialize(); //highlight line. } } } public void initialize() throws LifecycleException { //org.apache.catalina.connector.HttpConnector.initialize(). if (initialized) throw new LifecycleException ( sm.getString("httpConnector.alreadyInitialized")); this.initialized=true; Exception eRethrow = null; // Establish a server socket on the specified port try { serverSocket = open(); } catch (IOException ioe) { log("httpConnector, io problem: ", ioe); eRethrow = ioe; } catch (KeyStoreException kse) { log("httpConnector, keystore problem: ", kse); eRethrow = kse; } catch (NoSuchAlgorithmException nsae) { log("httpConnector, keystore algorithm problem: ", nsae); eRethrow = nsae; } catch (CertificateException ce) { log("httpConnector, certificate problem: ", ce); eRethrow = ce; } catch (UnrecoverableKeyException uke) { log("httpConnector, unrecoverable key: ", uke); eRethrow = uke; } catch (KeyManagementException kme) { log("httpConnector, key management problem: ", kme); eRethrow = kme; } if ( eRethrow != null ) throw new LifecycleException(threadName + ".open", eRethrow); }
public void start() throws LifecycleException { // org.apache.catalina.core.StandardService.start() // Validate and update our current component state if (started) { throw new LifecycleException (sm.getString("standardService.start.started")); } // Notify our interested LifecycleListeners lifecycle.fireLifecycleEvent(BEFORE_START_EVENT, null); System.out.println (sm.getString("standardService.start.name", this.name)); lifecycle.fireLifecycleEvent(START_EVENT, null); started = true; // Start our defined Container first if (container != null) { synchronized (container) { if (container instanceof Lifecycle) { ((Lifecycle) container).start(); //highlight line. } } } // Start our defined Connectors second synchronized (connectors) { for (int i = 0; i < connectors.length; i++) { if (connectors[i] instanceof Lifecycle) ((Lifecycle) connectors[i]).start(); //highlight line. } } // Notify our interested LifecycleListeners lifecycle.fireLifecycleEvent(AFTER_START_EVENT, null); }
public void stop() throws LifecycleException { // org.apache.catalina.core.StandardService.stop() // Validate and update our current component state if (!started) { throw new LifecycleException (sm.getString("standardService.stop.notStarted")); } // Notify our interested LifecycleListeners lifecycle.fireLifecycleEvent(BEFORE_STOP_EVENT, null); lifecycle.fireLifecycleEvent(STOP_EVENT, null); System.out.println (sm.getString("standardService.stop.name", this.name)); started = false; // Stop our defined Connectors first synchronized (connectors) { for (int i = 0; i < connectors.length; i++) { if (connectors[i] instanceof Lifecycle) ((Lifecycle) connectors[i]).stop();//highlight line. } } // Stop our defined Container second if (container != null) { synchronized (container) { if (container instanceof Lifecycle) { ((Lifecycle) container).stop(); //highlight line. } } } // Notify our interested LifecycleListeners lifecycle.fireLifecycleEvent(AFTER_STOP_EVENT, null); }
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 will call all its connector's 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); } } } }
step1)该方法会创建一个连接器,两个Wrapper实例,一个Context容器,一个Host容器和一个Engine容器;step2)将两个Wrapper 实例添加到 Context容器中, 将Context容器添加到 Host容器中,再将Host容器添加到Engine容器中;(干货——到此,tomcat的4种容器创建完毕)step3)但是,这并没有将连接器和最顶层的容器Engine相关联;step4)相反,main()方法创建了一个Service对象,设置其名称,再创建一个 Server对象,将Service实例添加到 Server实例中:Service service = new StandardService(); service.setName("Stand-alone Service"); Server server = new StandardServer(); server.addService(service);step5)main()方法将连接器和Engine容器添加到 Service实例中;service.addConnector(connector); service.setContainer(engine);step6)main()方法调用 Server.intialize() 和 Server.start()方法,初始化连接器,并启动连接器和servlet容器;step7)接下来,main()方法调用Server.await()方法,进入循环等待,监听8085端口等待关闭命令;(干货——参见上述【2.4】await()方法)
Attention)此时连接器已经处于运行状态,等待另一个端口8080上的 http 请求;(监听8085和8080端口分别处于不同的线程)
// Start the new server if (server instanceof Lifecycle) { try { server.initialize(); // step6 ((Lifecycle) server).start(); // step6 server.await(); // step7 // the program waits until the await method returns, // i.e. until a shutdown command is received. } catch (LifecycleException e) { e.printStackTrace(System.out); } }step8)除非收到了正确的关闭命令,否则await()方法是不会返回的。当 await()方法返回时,main()方法调用 Server.stop()方法,实际上关闭其所有组件;// Shut down the server if (server instanceof Lifecycle) { try { ((Lifecycle) server).stop(); } catch (LifecycleException e) { e.printStackTrace(System.out); } }
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."); } } }
对以上代码的分析(Analysis): Stopper类的main()方法会创建一个 Socket对象,然后将正确 的关闭命令 “SHOTDOWN”字符串发送到 端口8085。Catalina 服务器在接收到关闭命令后,就会执行相应的关闭操作;
E:\bench-cluster\cloud-data-preprocess\HowTomcatWorks\src>java -cp .;lib/servlet.jar;lib/catalina_4_1_24.jar;lib/catalina-5.5.4.jar;lib/naming-common. jar;lib/commons-collections.jar;lib/naming-resources.jar;lib/commons-digester.jar;lib/catalina.jar;E:\bench-cluster\cloud-data-preprocess\HowTomcatWok s\weroot com.tomcat.chapter14.startup.Bootstrap HttpConnector Opening server socket on all host IP addresses Starting service Stand-alone Service Apache Tomcat/4.1.24 WebappLoader[/app1]: Deploying class repositories to work directory E:\bench-cluster\cloud-data-preprocess\HowTomcatWorks\src\work\_\localhost\app1 WebappLoader[/app1]: Deploy class files /WEB-INF/classes to E:\bench-cluster\cloud-data-preprocess\HowTomcatWorks\src\webapps\app1\WEB-INF\classes StandardManager[/app1]: Seeding random number generator class java.security.SecureRandom StandardManager[/app1]: Seeding of random number generator has been completed StandardManager[/app1]: IOException while loading persisted sessions: java.io.EOFException java.io.EOFException at java.io.ObjectInputStream$PeekInputStream.readFully(Unknown Source) at java.io.ObjectInputStream$BlockDataInputStream.readShort(Unknown Source) at java.io.ObjectInputStream.readStreamHeader(Unknown Source) at java.io.ObjectInputStream.<init>(Unknown Source) at org.apache.catalina.util.CustomObjectInputStream.<init>(CustomObjectInputStream.java:103) at org.apache.catalina.session.StandardManager.load(StandardManager.java:408) at org.apache.catalina.session.StandardManager.start(StandardManager.java:655) at org.apache.catalina.core.StandardContext.start(StandardContext.java:3570) at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1188) at org.apache.catalina.core.StandardHost.start(StandardHost.java:738) at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1188) at org.apache.catalina.core.StandardEngine.start(StandardEngine.java:347) at org.apache.catalina.core.StandardService.start(StandardService.java:497) at org.apache.catalina.core.StandardServer.start(StandardServer.java:2190) at com.tomcat.chapter14.startup.Bootstrap.main(Bootstrap.java:77) StandardManager[/app1]: Exception loading sessions from persistent storage java.io.EOFException at java.io.ObjectInputStream$PeekInputStream.readFully(Unknown Source) at java.io.ObjectInputStream$BlockDataInputStream.readShort(Unknown Source) at java.io.ObjectInputStream.readStreamHeader(Unknown Source) at java.io.ObjectInputStream.<init>(Unknown Source) at org.apache.catalina.util.CustomObjectInputStream.<init>(CustomObjectInputStream.java:103) at org.apache.catalina.session.StandardManager.load(StandardManager.java:408) at org.apache.catalina.session.StandardManager.start(StandardManager.java:655) at org.apache.catalina.core.StandardContext.start(StandardContext.java:3570) at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1188) at org.apache.catalina.core.StandardHost.start(StandardHost.java:738) at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1188) at org.apache.catalina.core.StandardEngine.start(StandardEngine.java:347) at org.apache.catalina.core.StandardService.start(StandardService.java:497) at org.apache.catalina.core.StandardServer.start(StandardServer.java:2190) at com.tomcat.chapter14.startup.Bootstrap.main(Bootstrap.java:77) HttpConnector[8080] Starting background thread ModernServlet -- init StandardHost[localhost]: MAPPING configuration error for request URI /favicon.ico
标签:
原文地址:http://blog.csdn.net/pacosonswjtu/article/details/51474873