基于之前案例的感性认识,Tomcat连接器源码解读2---连接器与其中HttpProcessor、response、request等对象的关系

  说明:本篇强调分析对象关系,而不是类关系,主要分析为何HttpProcessor还需要依赖上篇中的连接器?为何res/对象交由链接器创建且res/req本身也依赖连接器?他们是否真的就是杂乱的纠缠在一起的?

  • org.apache.catalina.connector.http.HttpProcessor
  1 package org.apache.catalina.connector.http;
  2 
  3 import java.io.EOFException;
  4 import java.io.IOException;
  5 import java.io.InputStream;
  6 import java.io.InterruptedIOException;
  7 import java.io.OutputStream;
  8 import java.net.Socket;
  9 import java.util.ArrayList;
 10 import java.util.Iterator;
 11 import java.util.Locale;
 12 import java.util.TreeMap;
 13 import javax.servlet.ServletException;
 14 import javax.servlet.http.Cookie;
 15 import javax.servlet.http.HttpServletRequest;
 16 import javax.servlet.http.HttpServletResponse;
 17 import org.apache.catalina.Lifecycle;
 18 import org.apache.catalina.LifecycleException;
 19 import org.apache.catalina.LifecycleListener;
 20 import org.apache.catalina.Logger;
 21 import org.apache.catalina.connector.http.DefaultHeaders;
 22 import org.apache.catalina.connector.http.HttpConnector;
 23 import org.apache.catalina.connector.http.HttpHeader;
 24 import org.apache.catalina.connector.http.HttpRequestImpl;
 25 import org.apache.catalina.connector.http.HttpRequestLine;
 26 import org.apache.catalina.connector.http.HttpResponseImpl;
 27 import org.apache.catalina.connector.http.SocketInputStream;
 28 import org.apache.catalina.util.FastHttpDateFormat;
 29 import org.apache.catalina.util.LifecycleSupport;
 30 import org.apache.catalina.util.RequestUtil;
 31 import org.apache.catalina.util.ServerInfo;
 32 import org.apache.catalina.util.StringManager;
 33 import org.apache.catalina.util.StringParser;
 34 
 35 final class HttpProcessor implements Lifecycle, Runnable {
 36     private static final String SERVER_INFO = ServerInfo.getServerInfo() + " (HTTP/1.1 Connector)";
 37     private boolean available = false;
 38     private HttpConnector connector = null;
 39     private int debug = 0;
 40     private int id = 0;
 41     private LifecycleSupport lifecycle = new LifecycleSupport(this);
 42     private static final String match = ";jsessionid=";
 43     private static final char[] SESSION_ID = ";jsessionid=".toCharArray();
 44     private StringParser parser = new StringParser();
 45     private String proxyName = null;
 46     private int proxyPort = 0;
 47     private HttpRequestImpl request = null;
 48     private HttpResponseImpl response = null;
 49     private int serverPort = 0;
 50     protected StringManager sm = StringManager.getManager("org.apache.catalina.connector.http");
 51     private Socket socket = null;
 52     private boolean started = false;
 53     private boolean stopped = false;
 54     private Thread thread = null;
 55     private String threadName = null;
 56     private Object threadSync = new Object();
 57     private boolean keepAlive = false;
 58     private boolean http11 = true;
 59     private boolean sendAck = false;
 60     private static final byte[] ack = (new String("HTTP/1.1 100 Continue\r\n\r\n")).getBytes();
 61     private static final byte[] CRLF = (new String("\r\n")).getBytes();
 62     private HttpRequestLine requestLine = new HttpRequestLine();
 63     private int status = 0;
 64 
 65     public HttpProcessor(HttpConnector connector, int id) {
 66         this.connector = connector;
 67         this.debug = connector.getDebug();
 68         this.id = id;
 69         this.proxyName = connector.getProxyName();
 70         this.proxyPort = connector.getProxyPort();
 71         this.request = (HttpRequestImpl) connector.createRequest();
 72         this.response = (HttpResponseImpl) connector.createResponse();
 73         this.serverPort = connector.getPort();
 74         this.threadName = "HttpProcessor[" + connector.getPort() + "][" + id + "]";
 75     }
 76 
 77     public String toString() {
 78         return this.threadName;
 79     }
 80 
 81     synchronized void assign(Socket socket) {
 82         while (this.available) {
 83             try {
 84                 this.wait();
 85             } catch (InterruptedException arg2) {
 86                 ;
 87             }
 88         }
 89 
 90         this.socket = socket;
 91         this.available = true;
 92         this.notifyAll();
 93         if (this.debug >= 1 && socket != null) {
 94             this.log(" An incoming request is being assigned");
 95         }
 96 
 97     }
 98 
 99     private synchronized Socket await() {
100         while (!this.available) {
101             try {
102                 this.wait();
103             } catch (InterruptedException arg1) {
104                 ;
105             }
106         }
107 
108         Socket socket = this.socket;
109         this.available = false;
110         this.notifyAll();
111         if (this.debug >= 1 && socket != null) {
112             this.log("  The incoming request has been awaited");
113         }
114 
115         return socket;
116     }
117 
118     private void log(String message) {
119         Logger logger = this.connector.getContainer().getLogger();
120         if (logger != null) {
121             logger.log(this.threadName + " " + message);
122         }
123 
124     }
125 
126     private void log(String message, Throwable throwable) {
127         Logger logger = this.connector.getContainer().getLogger();
128         if (logger != null) {
129             logger.log(this.threadName + " " + message, throwable);
130         }
131 
132     }
133 
134     private void parseAcceptLanguage(String value) {
135         TreeMap locales = new TreeMap();
136         int white = value.indexOf(32);
137         if (white < 0) {
138             white = value.indexOf(9);
139         }
140 
141         int keys;
142         int key;
143         if (white >= 0) {
144             StringBuffer length = new StringBuffer();
145             keys = value.length();
146 
147             for (key = 0; key < keys; ++key) {
148                 char list = value.charAt(key);
149                 if (list != 32 && list != 9) {
150                     length.append(list);
151                 }
152             }
153 
154             value = length.toString();
155         }
156 
157         this.parser.setString(value);
158         int arg18 = this.parser.getLength();
159 
160         while (true) {
161             keys = this.parser.getIndex();
162             if (keys >= arg18) {
163                 Iterator arg19 = locales.keySet().iterator();
164 
165                 while (arg19.hasNext()) {
166                     Double arg20 = (Double) arg19.next();
167                     ArrayList arg22 = (ArrayList) locales.get(arg20);
168 
169                     Locale locale;
170                     for (Iterator arg23 = arg22.iterator(); arg23.hasNext(); this.request.addLocale(locale)) {
171                         locale = (Locale) arg23.next();
172                         if (this.debug >= 1) {
173                             this.log(" Adding locale \'" + locale + "\'");
174                         }
175                     }
176                 }
177 
178                 return;
179             }
180 
181             key = this.parser.findChar(',');
182             String arg21 = this.parser.extract(keys, key).trim();
183             this.parser.advance();
184             double values = 1.0D;
185             int semi = arg21.indexOf(";q=");
186             if (semi >= 0) {
187                 try {
188                     values = Double.parseDouble(arg21.substring(semi + 3));
189                 } catch (NumberFormatException arg17) {
190                     values = 0.0D;
191                 }
192 
193                 arg21 = arg21.substring(0, semi);
194             }
195 
196             if (values >= 5.0E-5D && !"*".equals(arg21)) {
197                 String language = null;
198                 String country = null;
199                 String variant = null;
200                 int dash = arg21.indexOf(45);
201                 if (dash < 0) {
202                     language = arg21;
203                     country = "";
204                     variant = "";
205                 } else {
206                     language = arg21.substring(0, dash);
207                     country = arg21.substring(dash + 1);
208                     int locale1 = country.indexOf(45);
209                     if (locale1 > 0) {
210                         String key1 = country.substring(0, locale1);
211                         variant = country.substring(locale1 + 1);
212                         country = key1;
213                     } else {
214                         variant = "";
215                     }
216                 }
217 
218                 Locale arg24 = new Locale(language, country, variant);
219                 Double arg25 = new Double(-values);
220                 ArrayList values1 = (ArrayList) locales.get(arg25);
221                 if (values1 == null) {
222                     values1 = new ArrayList();
223                     locales.put(arg25, values1);
224                 }
225 
226                 values1.add(arg24);
227             }
228         }
229     }
230 
231     private void parseConnection(Socket socket) throws IOException, ServletException {
232         if (this.debug >= 2) {
233             this.log("  parseConnection: address=" + socket.getInetAddress() + ", port=" + this.connector.getPort());
234         }
235 
236         this.request.setInet(socket.getInetAddress());
237         if (this.proxyPort != 0) {
238             this.request.setServerPort(this.proxyPort);
239         } else {
240             this.request.setServerPort(this.serverPort);
241         }
242 
243         this.request.setSocket(socket);
244     }
245 
246     private void parseHeaders(SocketInputStream input) throws IOException, ServletException {
247         while (true) {
248             HttpHeader header = this.request.allocateHeader();
249             input.readHeader(header);
250             if (header.nameEnd == 0) {
251                 if (header.valueEnd == 0) {
252                     return;
253                 }
254 
255                 throw new ServletException(this.sm.getString("httpProcessor.parseHeaders.colon"));
256             }
257 
258             String value = new String(header.value, 0, header.valueEnd);
259             if (this.debug >= 1) {
260                 this.log(" Header " + new String(header.name, 0, header.nameEnd) + " = " + value);
261             }
262 
263             if (header.equals(DefaultHeaders.AUTHORIZATION_NAME)) {
264                 this.request.setAuthorization(value);
265             } else if (header.equals(DefaultHeaders.ACCEPT_LANGUAGE_NAME)) {
266                 this.parseAcceptLanguage(value);
267             } else {
268                 int port;
269                 if (header.equals(DefaultHeaders.COOKIE_NAME)) {
270                     Cookie[] n = RequestUtil.parseCookieHeader(value);
271 
272                     for (port = 0; port < n.length; ++port) {
273                         if (n[port].getName().equals("JSESSIONID") && !this.request.isRequestedSessionIdFromCookie()) {
274                             this.request.setRequestedSessionId(n[port].getValue());
275                             this.request.setRequestedSessionCookie(true);
276                             this.request.setRequestedSessionURL(false);
277                             if (this.debug >= 1) {
278                                 this.log(" Requested cookie session id is "
279                                         + ((HttpServletRequest) this.request.getRequest()).getRequestedSessionId());
280                             }
281                         }
282 
283                         if (this.debug >= 1) {
284                             this.log(" Adding cookie " + n[port].getName() + "=" + n[port].getValue());
285                         }
286 
287                         this.request.addCookie(n[port]);
288                     }
289                 } else {
290                     int arg9;
291                     if (header.equals(DefaultHeaders.CONTENT_LENGTH_NAME)) {
292                         boolean arg8 = true;
293 
294                         try {
295                             arg9 = Integer.parseInt(value);
296                         } catch (Exception arg7) {
297                             throw new ServletException(this.sm.getString("httpProcessor.parseHeaders.contentLength"));
298                         }
299 
300                         this.request.setContentLength(arg9);
301                     } else if (header.equals(DefaultHeaders.CONTENT_TYPE_NAME)) {
302                         this.request.setContentType(value);
303                     } else if (header.equals(DefaultHeaders.HOST_NAME)) {
304                         arg9 = value.indexOf(58);
305                         if (arg9 < 0) {
306                             if (this.connector.getScheme().equals("http")) {
307                                 this.request.setServerPort(80);
308                             } else if (this.connector.getScheme().equals("https")) {
309                                 this.request.setServerPort(443);
310                             }
311 
312                             if (this.proxyName != null) {
313                                 this.request.setServerName(this.proxyName);
314                             } else {
315                                 this.request.setServerName(value);
316                             }
317                         } else {
318                             if (this.proxyName != null) {
319                                 this.request.setServerName(this.proxyName);
320                             } else {
321                                 this.request.setServerName(value.substring(0, arg9).trim());
322                             }
323 
324                             if (this.proxyPort != 0) {
325                                 this.request.setServerPort(this.proxyPort);
326                             } else {
327                                 boolean arg10 = true;
328 
329                                 try {
330                                     port = Integer.parseInt(value.substring(arg9 + 1).trim());
331                                 } catch (Exception arg6) {
332                                     throw new ServletException(
333                                             this.sm.getString("httpProcessor.parseHeaders.portNumber"));
334                                 }
335 
336                                 this.request.setServerPort(port);
337                             }
338                         }
339                     } else if (header.equals(DefaultHeaders.CONNECTION_NAME)) {
340                         if (header.valueEquals(DefaultHeaders.CONNECTION_CLOSE_VALUE)) {
341                             this.keepAlive = false;
342                             this.response.setHeader("Connection", "close");
343                         }
344                     } else if (header.equals(DefaultHeaders.EXPECT_NAME)) {
345                         if (!header.valueEquals(DefaultHeaders.EXPECT_100_VALUE)) {
346                             throw new ServletException(
347                                     this.sm.getString("httpProcessor.parseHeaders.unknownExpectation"));
348                         }
349 
350                         this.sendAck = true;
351                     } else if (header.equals(DefaultHeaders.TRANSFER_ENCODING_NAME)) {
352                         ;
353                     }
354                 }
355             }
356 
357             this.request.nextHeader();
358         }
359     }
360 
361     private void parseRequest(SocketInputStream input, OutputStream output) throws IOException, ServletException {
362         input.readRequestLine(this.requestLine);
363         this.status = 1;
364         String method = new String(this.requestLine.method, 0, this.requestLine.methodEnd);
365         String uri = null;
366         String protocol = new String(this.requestLine.protocol, 0, this.requestLine.protocolEnd);
367         if (protocol.length() == 0) {
368             protocol = "HTTP/0.9";
369         }
370 
371         if (protocol.equals("HTTP/1.1")) {
372             this.http11 = true;
373             this.sendAck = false;
374         } else {
375             this.http11 = false;
376             this.sendAck = false;
377             this.keepAlive = false;
378         }
379 
380         if (method.length() < 1) {
381             throw new ServletException(this.sm.getString("httpProcessor.parseRequest.method"));
382         } else if (this.requestLine.uriEnd < 1) {
383             throw new ServletException(this.sm.getString("httpProcessor.parseRequest.uri"));
384         } else {
385             int question = this.requestLine.indexOf("?");
386             if (question >= 0) {
387                 this.request.setQueryString(
388                         new String(this.requestLine.uri, question + 1, this.requestLine.uriEnd - question - 1));
389                 if (this.debug >= 1) {
390                     this.log(" Query string is " + ((HttpServletRequest) this.request.getRequest()).getQueryString());
391                 }
392 
393                 uri = new String(this.requestLine.uri, 0, question);
394             } else {
395                 this.request.setQueryString((String) null);
396                 uri = new String(this.requestLine.uri, 0, this.requestLine.uriEnd);
397             }
398 
399             int semicolon;
400             if (!uri.startsWith("/")) {
401                 semicolon = uri.indexOf("://");
402                 if (semicolon != -1) {
403                     semicolon = uri.indexOf(47, semicolon + 3);
404                     if (semicolon == -1) {
405                         uri = "";
406                     } else {
407                         uri = uri.substring(semicolon);
408                     }
409                 }
410             }
411 
412             semicolon = uri.indexOf(";jsessionid=");
413             String normalizedUri;
414             if (semicolon >= 0) {
415                 normalizedUri = uri.substring(semicolon + ";jsessionid=".length());
416                 int semicolon2 = normalizedUri.indexOf(59);
417                 if (semicolon2 >= 0) {
418                     this.request.setRequestedSessionId(normalizedUri.substring(0, semicolon2));
419                     normalizedUri = normalizedUri.substring(semicolon2);
420                 } else {
421                     this.request.setRequestedSessionId(normalizedUri);
422                     normalizedUri = "";
423                 }
424 
425                 this.request.setRequestedSessionURL(true);
426                 uri = uri.substring(0, semicolon) + normalizedUri;
427                 if (this.debug >= 1) {
428                     this.log(" Requested URL session id is "
429                             + ((HttpServletRequest) this.request.getRequest()).getRequestedSessionId());
430                 }
431             } else {
432                 this.request.setRequestedSessionId((String) null);
433                 this.request.setRequestedSessionURL(false);
434             }
435 
436             normalizedUri = this.normalize(uri);
437             if (this.debug >= 1) {
438                 this.log("Normalized: \'" + uri + "\' to \'" + normalizedUri + "\'");
439             }
440 
441             this.request.setMethod(method);
442             this.request.setProtocol(protocol);
443             if (normalizedUri != null) {
444                 this.request.setRequestURI(normalizedUri);
445             } else {
446                 this.request.setRequestURI(uri);
447             }
448 
449             this.request.setSecure(this.connector.getSecure());
450             this.request.setScheme(this.connector.getScheme());
451             if (normalizedUri == null) {
452                 this.log(" Invalid request URI: \'" + uri + "\'");
453                 throw new ServletException("Invalid URI: " + uri + "\'");
454             } else {
455                 if (this.debug >= 1) {
456                     this.log(" Request is \'" + method + "\' for \'" + uri + "\' with protocol \'" + protocol + "\'");
457                 }
458 
459             }
460         }
461     }
462 
463     protected String normalize(String path) {
464         if (path == null) {
465             return null;
466         } else {
467             String normalized = path;
468             if (path.startsWith("/%7E") || path.startsWith("/%7e")) {
469                 normalized = "/~" + path.substring(4);
470             }
471 
472             if (normalized.indexOf("%25") < 0 && normalized.indexOf("%2F") < 0 && normalized.indexOf("%2E") < 0
473                     && normalized.indexOf("%5C") < 0 && normalized.indexOf("%2f") < 0 && normalized.indexOf("%2e") < 0
474                     && normalized.indexOf("%5c") < 0) {
475                 if (normalized.equals("/.")) {
476                     return "/";
477                 } else {
478                     if (normalized.indexOf(92) >= 0) {
479                         normalized = normalized.replace('\\', '/');
480                     }
481 
482                     if (!normalized.startsWith("/")) {
483                         normalized = "/" + normalized;
484                     }
485 
486                     while (true) {
487                         int index = normalized.indexOf("//");
488                         if (index < 0) {
489                             while (true) {
490                                 index = normalized.indexOf("/./");
491                                 if (index < 0) {
492                                     while (true) {
493                                         index = normalized.indexOf("/../");
494                                         if (index < 0) {
495                                             return normalized.indexOf("/...") >= 0 ? null : normalized;
496                                         }
497 
498                                         if (index == 0) {
499                                             return null;
500                                         }
501 
502                                         int index2 = normalized.lastIndexOf(47, index - 1);
503                                         normalized = normalized.substring(0, index2) + normalized.substring(index + 3);
504                                     }
505                                 }
506 
507                                 normalized = normalized.substring(0, index) + normalized.substring(index + 2);
508                             }
509                         }
510 
511                         normalized = normalized.substring(0, index) + normalized.substring(index + 1);
512                     }
513                 }
514             } else {
515                 return null;
516             }
517         }
518     }
519 
520     private void ackRequest(OutputStream output) throws IOException {
521         if (this.sendAck) {
522             output.write(ack);
523         }
524 
525     }
526 
527     private void process(Socket socket) {
528         boolean ok = true;
529         boolean finishResponse = true;
530         SocketInputStream input = null;
531         OutputStream output = null;
532 
533         try {
534             input = new SocketInputStream(socket.getInputStream(), this.connector.getBufferSize());
535         } catch (Exception arg26) {
536             this.log("process.create", arg26);
537             ok = false;
538         }
539 
540         this.keepAlive = true;
541 
542         while (!this.stopped && ok && this.keepAlive) {
543             finishResponse = true;
544 
545             try {
546                 this.request.setStream(input);
547                 this.request.setResponse(this.response);
548                 output = socket.getOutputStream();
549                 this.response.setStream(output);
550                 this.response.setRequest(this.request);
551                 ((HttpServletResponse) this.response.getResponse()).setHeader("Server", SERVER_INFO);
552             } catch (Exception arg25) {
553                 this.log("process.create", arg25);
554                 ok = false;
555             }
556 
557             try {
558                 if (ok) {
559                     this.parseConnection(socket);
560                     this.parseRequest(input, output);
561                     if (!this.request.getRequest().getProtocol().startsWith("HTTP/0")) {
562                         this.parseHeaders(input);
563                     }
564 
565                     if (this.http11) {
566                         this.ackRequest(output);
567                         if (this.connector.isChunkingAllowed()) {
568                             this.response.setAllowChunking(true);
569                         }
570                     }
571                 }
572             } catch (EOFException arg27) {
573                 ok = false;
574                 finishResponse = false;
575             } catch (ServletException arg28) {
576                 ok = false;
577 
578                 try {
579                     ((HttpServletResponse) this.response.getResponse()).sendError(400);
580                 } catch (Exception arg24) {
581                     ;
582                 }
583             } catch (InterruptedIOException arg29) {
584                 InterruptedIOException e = arg29;
585                 if (this.debug > 1) {
586                     try {
587                         this.log("process.parse", e);
588                         ((HttpServletResponse) this.response.getResponse()).sendError(400);
589                     } catch (Exception arg23) {
590                         ;
591                     }
592                 }
593 
594                 ok = false;
595             } catch (Exception arg30) {
596                 Exception f = arg30;
597 
598                 try {
599                     this.log("process.parse", f);
600                     ((HttpServletResponse) this.response.getResponse()).sendError(400);
601                 } catch (Exception arg22) {
602                     ;
603                 }
604 
605                 ok = false;
606             }
607 
608             try {
609                 this.response.setHeader("Date", FastHttpDateFormat.getCurrentDate());
610                 if (ok) {
611                     this.connector.getContainer().invoke(this.request, this.response);
612                 }
613             } catch (ServletException arg19) {
614                 this.log("process.invoke", arg19);
615 
616                 try {
617                     ((HttpServletResponse) this.response.getResponse()).sendError(500);
618                 } catch (Exception arg18) {
619                     ;
620                 }
621 
622                 ok = false;
623             } catch (InterruptedIOException arg20) {
624                 ok = false;
625             } catch (Throwable arg21) {
626                 this.log("process.invoke", arg21);
627 
628                 try {
629                     ((HttpServletResponse) this.response.getResponse()).sendError(500);
630                 } catch (Exception arg17) {
631                     ;
632                 }
633 
634                 ok = false;
635             }
636 
637             if (finishResponse) {
638                 try {
639                     this.response.finishResponse();
640                 } catch (IOException arg15) {
641                     ok = false;
642                 } catch (Throwable arg16) {
643                     this.log("process.invoke", arg16);
644                     ok = false;
645                 }
646 
647                 try {
648                     this.request.finishRequest();
649                 } catch (IOException arg13) {
650                     ok = false;
651                 } catch (Throwable arg14) {
652                     this.log("process.invoke", arg14);
653                     ok = false;
654                 }
655 
656                 try {
657                     if (output != null) {
658                         output.flush();
659                     }
660                 } catch (IOException arg12) {
661                     ok = false;
662                 }
663             }
664 
665             if ("close".equals(this.response.getHeader("Connection"))) {
666                 this.keepAlive = false;
667             }
668 
669             this.status = 0;
670             this.request.recycle();
671             this.response.recycle();
672         }
673 
674         try {
675             this.shutdownInput(input);
676             socket.close();
677         } catch (IOException arg10) {
678             ;
679         } catch (Throwable arg11) {
680             this.log("process.invoke", arg11);
681         }
682 
683         socket = null;
684     }
685 
686     protected void shutdownInput(InputStream input) {
687         try {
688             int e = input.available();
689             if (e > 0) {
690                 input.skip((long) e);
691             }
692         } catch (Throwable arg2) {
693             ;
694         }
695 
696     }
697 
698     public void run() {
699         while (!this.stopped) {
700             Socket socket = this.await();
701             if (socket != null) {
702                 try {
703                     this.process(socket);
704                 } catch (Throwable arg4) {
705                     this.log("process.invoke", arg4);
706                 }
707 
708                 this.connector.recycle(this);
709             }
710         }
711 
712         Object socket1 = this.threadSync;
713         synchronized (socket1) {
714             this.threadSync.notifyAll();
715         }
716     }
717 
718     private void threadStart() {
719         this.log(this.sm.getString("httpProcessor.starting"));
720         this.thread = new Thread(this, this.threadName);
721         this.thread.setDaemon(true);
722         this.thread.start();
723         if (this.debug >= 1) {
724             this.log(" Background thread has been started");
725         }
726 
727     }
728 
729     private void threadStop() {
730         this.log(this.sm.getString("httpProcessor.stopping"));
731         this.stopped = true;
732         this.assign((Socket) null);
733         if (this.status != 0) {
734             Object arg0 = this.threadSync;
735             synchronized (arg0) {
736                 try {
737                     this.threadSync.wait(5000L);
738                 } catch (InterruptedException arg3) {
739                     ;
740                 }
741             }
742         }
743 
744         this.thread = null;
745     }
746 
747     public void addLifecycleListener(LifecycleListener listener) {
748         this.lifecycle.addLifecycleListener(listener);
749     }
750 
751     public LifecycleListener[] findLifecycleListeners() {
752         return this.lifecycle.findLifecycleListeners();
753     }
754 
755     public void removeLifecycleListener(LifecycleListener listener) {
756         this.lifecycle.removeLifecycleListener(listener);
757     }
758 
759     public void start() throws LifecycleException {
760         if (this.started) {
761             throw new LifecycleException(this.sm.getString("httpProcessor.alreadyStarted"));
762         } else {
763             this.lifecycle.fireLifecycleEvent("start", (Object) null);
764             this.started = true;
765             this.threadStart();
766         }
767     }
768 
769     public void stop() throws LifecycleException {
770         if (!this.started) {
771             throw new LifecycleException(this.sm.getString("httpProcessor.notStarted"));
772         } else {
773             this.lifecycle.fireLifecycleEvent("stop", (Object) null);
774             this.started = false;
775             this.threadStop();
776         }
777     }
778 }
View Code

  分析:程序入口是上一篇笔记中的HttpProcessor的start方法和assign()方法,

猜你喜欢

转载自www.cnblogs.com/10000miles/p/9230568.html