基于之前案例的感性认识,Tomcat连接器源码解读。

  背景:本篇的内容主体是Connector连接器,暂不明确其在Tomcat中与其他容器的关系,但可以前述案例为标的物,把Connector理解为运行在多线程下,等待获取客户端socket并交由HttpProcessor进行处理的Object。那么关注点就是在Tomcat中完整的Connector及其所关联的组件的关系,整个模块的相关流程。上篇中的疑问仍留,Response请求头 属性怎样填充?如何填充?不知道在这里有没有解答。

  •     catalina.jar包org.apache.catalina.Connector接口
 1 package org.apache.catalina;
 2 
 3 import org.apache.catalina.Container;
 4 import org.apache.catalina.LifecycleException;
 5 import org.apache.catalina.Request;
 6 import org.apache.catalina.Response;
 7 import org.apache.catalina.Service;
 8 import org.apache.catalina.net.ServerSocketFactory;
 9 
10 public interface Connector {
11     Container getContainer();
12 
13     void setContainer(Container arg0);
14 
15     boolean getEnableLookups();
16 
17     void setEnableLookups(boolean arg0);
18 
19     ServerSocketFactory getFactory();
20 
21     void setFactory(ServerSocketFactory arg0);
22 
23     String getInfo();
24 
25     int getRedirectPort();
26 
27     void setRedirectPort(int arg0);
28 
29     String getScheme();
30 
31     void setScheme(String arg0);
32 
33     boolean getSecure();
34 
35     void setSecure(boolean arg0);
36 
37     Service getService();
38 
39     void setService(Service arg0);
40 
41     Request createRequest();
42 
43     Response createResponse();
44 
45     void initialize() throws LifecycleException;
46 }
代码清单

  类关系:可以看到接口import了Container、Request、Response、Service、ServerSocketFactory,因此它们将或依赖或聚合在该类中,是该类分解出去的组成部分。它们将      在实现类中被其声明为属性;接口中定义的方法,由于版本问题源码中没有文档注释,Service/ServiceScoketFactory等在前述案例中没有使用到的类的具体作用不得      而知,仅仅是抽象层面的依赖关系,并不足以获取更多的信息。还需要有方法体,来分析对象之间的动态关系,下面是其实现类。

  • catalina.jar包org.apache.catalina.connector.Http.HttpConnector类
  1 package org.apache.catalina.connector.http;
  2 
  3 import java.io.IOException;
  4 import java.net.BindException;
  5 import java.net.InetAddress;
  6 import java.net.ServerSocket;
  7 import java.net.Socket;
  8 import java.security.AccessControlException;
  9 import java.security.KeyManagementException;
 10 import java.security.KeyStoreException;
 11 import java.security.NoSuchAlgorithmException;
 12 import java.security.UnrecoverableKeyException;
 13 import java.security.cert.CertificateException;
 14 import java.util.Stack;
 15 import java.util.Vector;
 16 import org.apache.catalina.Connector;
 17 import org.apache.catalina.Container;
 18 import org.apache.catalina.Lifecycle;
 19 import org.apache.catalina.LifecycleException;
 20 import org.apache.catalina.LifecycleListener;
 21 import org.apache.catalina.Logger;
 22 import org.apache.catalina.Request;
 23 import org.apache.catalina.Response;
 24 import org.apache.catalina.Service;
 25 import org.apache.catalina.connector.http.HttpProcessor;
 26 import org.apache.catalina.connector.http.HttpRequestImpl;
 27 import org.apache.catalina.connector.http.HttpResponseImpl;
 28 import org.apache.catalina.net.DefaultServerSocketFactory;
 29 import org.apache.catalina.net.ServerSocketFactory;
 30 import org.apache.catalina.util.LifecycleSupport;
 31 import org.apache.catalina.util.StringManager;
 32 
 33 public final class HttpConnector implements Connector, Lifecycle, Runnable {
 34     private Service service = null;
 35     private int acceptCount = 10;
 36     private String address = null;
 37     private int bufferSize = 2048;
 38     protected Container container = null;
 39     private Vector created = new Vector();
 40     private int curProcessors = 0;
 41     private int debug = 0;
 42     private boolean enableLookups = false;
 43     private ServerSocketFactory factory = null;
 44     private static final String info = "org.apache.catalina.connector.http.HttpConnector/1.0";
 45     protected LifecycleSupport lifecycle = new LifecycleSupport(this);
 46     protected int minProcessors = 5;
 47     private int maxProcessors = 20;
 48     private int connectionTimeout = '';
 49     private int port = 8080;
 50     private Stack processors = new Stack();
 51     private String proxyName = null;
 52     private int proxyPort = 0;
 53     private int redirectPort = 443;
 54     private String scheme = "http";
 55     private boolean secure = false;
 56     private ServerSocket serverSocket = null;
 57     private StringManager sm = StringManager.getManager("org.apache.catalina.connector.http");
 58     private boolean initialized = false;
 59     private boolean started = false;
 60     private boolean stopped = false;
 61     private Thread thread = null;
 62     private String threadName = null;
 63     private Object threadSync = new Object();
 64     private boolean allowChunking = true;
 65     private boolean tcpNoDelay = true;
 66 
 67     public Service getService() {
 68         return this.service;
 69     }
 70 
 71     public void setService(Service service) {
 72         this.service = service;
 73     }
 74 
 75     public int getConnectionTimeout() {
 76         return this.connectionTimeout;
 77     }
 78 
 79     public void setConnectionTimeout(int connectionTimeout) {
 80         this.connectionTimeout = connectionTimeout;
 81     }
 82 
 83     public int getAcceptCount() {
 84         return this.acceptCount;
 85     }
 86 
 87     public void setAcceptCount(int count) {
 88         this.acceptCount = count;
 89     }
 90 
 91     public boolean isChunkingAllowed() {
 92         return this.allowChunking;
 93     }
 94 
 95     public boolean getAllowChunking() {
 96         return this.isChunkingAllowed();
 97     }
 98 
 99     public void setAllowChunking(boolean allowChunking) {
100         this.allowChunking = allowChunking;
101     }
102 
103     public String getAddress() {
104         return this.address;
105     }
106 
107     public void setAddress(String address) {
108         this.address = address;
109     }
110 
111     public boolean isAvailable() {
112         return this.started;
113     }
114 
115     public int getBufferSize() {
116         return this.bufferSize;
117     }
118 
119     public void setBufferSize(int bufferSize) {
120         this.bufferSize = bufferSize;
121     }
122 
123     public Container getContainer() {
124         return this.container;
125     }
126 
127     public void setContainer(Container container) {
128         this.container = container;
129     }
130 
131     public int getCurProcessors() {
132         return this.curProcessors;
133     }
134 
135     public int getDebug() {
136         return this.debug;
137     }
138 
139     public void setDebug(int debug) {
140         this.debug = debug;
141     }
142 
143     public boolean getEnableLookups() {
144         return this.enableLookups;
145     }
146 
147     public void setEnableLookups(boolean enableLookups) {
148         this.enableLookups = enableLookups;
149     }
150 
151     public ServerSocketFactory getFactory() {
152         if (this.factory == null) {
153             synchronized (this) {
154                 this.factory = new DefaultServerSocketFactory();
155             }
156         }
157 
158         return this.factory;
159     }
160 
161     public void setFactory(ServerSocketFactory factory) {
162         this.factory = factory;
163     }
164 
165     public String getInfo() {
166         return "org.apache.catalina.connector.http.HttpConnector/1.0";
167     }
168 
169     public int getMinProcessors() {
170         return this.minProcessors;
171     }
172 
173     public void setMinProcessors(int minProcessors) {
174         this.minProcessors = minProcessors;
175     }
176 
177     public int getMaxProcessors() {
178         return this.maxProcessors;
179     }
180 
181     public void setMaxProcessors(int maxProcessors) {
182         this.maxProcessors = maxProcessors;
183     }
184 
185     public int getPort() {
186         return this.port;
187     }
188 
189     public void setPort(int port) {
190         this.port = port;
191     }
192 
193     public String getProxyName() {
194         return this.proxyName;
195     }
196 
197     public void setProxyName(String proxyName) {
198         this.proxyName = proxyName;
199     }
200 
201     public int getProxyPort() {
202         return this.proxyPort;
203     }
204 
205     public void setProxyPort(int proxyPort) {
206         this.proxyPort = proxyPort;
207     }
208 
209     public int getRedirectPort() {
210         return this.redirectPort;
211     }
212 
213     public void setRedirectPort(int redirectPort) {
214         this.redirectPort = redirectPort;
215     }
216 
217     public String getScheme() {
218         return this.scheme;
219     }
220 
221     public void setScheme(String scheme) {
222         this.scheme = scheme;
223     }
224 
225     public boolean getSecure() {
226         return this.secure;
227     }
228 
229     public void setSecure(boolean secure) {
230         this.secure = secure;
231     }
232 
233     public boolean getTcpNoDelay() {
234         return this.tcpNoDelay;
235     }
236 
237     public void setTcpNoDelay(boolean tcpNoDelay) {
238         this.tcpNoDelay = tcpNoDelay;
239     }
240 
241     public Request createRequest() {
242         HttpRequestImpl request = new HttpRequestImpl();
243         request.setConnector(this);
244         return request;
245     }
246 
247     public Response createResponse() {
248         HttpResponseImpl response = new HttpResponseImpl();
249         response.setConnector(this);
250         return response;
251     }
252 
253     void recycle(HttpProcessor processor) {
254         this.processors.push(processor);
255     }
256 
257     private HttpProcessor createProcessor() {
258         Stack arg0 = this.processors;
259         synchronized (arg0) {
260             HttpProcessor arg1;
261             if (this.processors.size() > 0) {
262                 arg1 = (HttpProcessor) this.processors.pop();
263                 return arg1;
264             } else if (this.maxProcessors > 0 && this.curProcessors < this.maxProcessors) {
265                 arg1 = this.newProcessor();
266                 return arg1;
267             } else if (this.maxProcessors < 0) {
268                 arg1 = this.newProcessor();
269                 return arg1;
270             } else {
271                 arg1 = null;
272                 return arg1;
273             }
274         }
275     }
276 
277     private void log(String message) {
278         Logger logger = this.container.getLogger();
279         String localName = this.threadName;
280         if (localName == null) {
281             localName = "HttpConnector";
282         }
283 
284         if (logger != null) {
285             logger.log(localName + " " + message);
286         } else {
287             System.out.println(localName + " " + message);
288         }
289 
290     }
291 
292     private void log(String message, Throwable throwable) {
293         Logger logger = this.container.getLogger();
294         String localName = this.threadName;
295         if (localName == null) {
296             localName = "HttpConnector";
297         }
298 
299         if (logger != null) {
300             logger.log(localName + " " + message, throwable);
301         } else {
302             System.out.println(localName + " " + message);
303             throwable.printStackTrace(System.out);
304         }
305 
306     }
307 
308     private HttpProcessor newProcessor() {
309         HttpProcessor processor = new HttpProcessor(this, this.curProcessors++);
310         if (processor instanceof Lifecycle) {
311             try {
312                 processor.start();
313             } catch (LifecycleException arg2) {
314                 this.log("newProcessor", arg2);
315                 return null;
316             }
317         }
318 
319         this.created.addElement(processor);
320         return processor;
321     }
322 
323     private ServerSocket open() throws IOException, KeyStoreException, NoSuchAlgorithmException, CertificateException,
324             UnrecoverableKeyException, KeyManagementException {
325         ServerSocketFactory factory = this.getFactory();
326         if (this.address == null) {
327             this.log(this.sm.getString("httpConnector.allAddresses"));
328 
329             try {
330                 return factory.createSocket(this.port, this.acceptCount);
331             } catch (BindException arg4) {
332                 throw new BindException(arg4.getMessage() + ":" + this.port);
333             }
334         } else {
335             try {
336                 InetAddress e = InetAddress.getByName(this.address);
337                 this.log(this.sm.getString("httpConnector.anAddress", this.address));
338 
339                 try {
340                     return factory.createSocket(this.port, this.acceptCount, e);
341                 } catch (BindException arg5) {
342                     throw new BindException(arg5.getMessage() + ":" + this.address + ":" + this.port);
343                 }
344             } catch (Exception arg6) {
345                 this.log(this.sm.getString("httpConnector.noAddress", this.address));
346 
347                 try {
348                     return factory.createSocket(this.port, this.acceptCount);
349                 } catch (BindException arg3) {
350                     throw new BindException(arg3.getMessage() + ":" + this.port);
351                 }
352             }
353         }
354     }
355 
356     public void run() {
357         while (true) {
358             Object socket;
359             if (!this.stopped) {
360                 label81 : {
361                     socket = null;
362 
363                     Socket socket1;
364                     try {
365                         socket1 = this.serverSocket.accept();
366                         if (this.connectionTimeout > 0) {
367                             socket1.setSoTimeout(this.connectionTimeout);
368                         }
369 
370                         socket1.setTcpNoDelay(this.tcpNoDelay);
371                     } catch (AccessControlException arg19) {
372                         this.log("socket accept security exception", arg19);
373                         continue;
374                     } catch (IOException arg20) {
375                         IOException e = arg20;
376 
377                         try {
378                             Object ioe = this.threadSync;
379                             synchronized (ioe) {
380                                 if (this.started && !this.stopped) {
381                                     this.log("accept error: ", e);
382                                 }
383 
384                                 if (!this.stopped) {
385                                     this.serverSocket.close();
386                                     this.serverSocket = this.open();
387                                 }
388                                 continue;
389                             }
390                         } catch (IOException arg12) {
391                             this.log("socket reopen, io problem: ", arg12);
392                             break label81;
393                         } catch (KeyStoreException arg13) {
394                             this.log("socket reopen, keystore problem: ", arg13);
395                             break label81;
396                         } catch (NoSuchAlgorithmException arg14) {
397                             this.log("socket reopen, keystore algorithm problem: ", arg14);
398                             break label81;
399                         } catch (CertificateException arg15) {
400                             this.log("socket reopen, certificate problem: ", arg15);
401                             break label81;
402                         } catch (UnrecoverableKeyException arg16) {
403                             this.log("socket reopen, unrecoverable key: ", arg16);
404                             break label81;
405                         } catch (KeyManagementException arg17) {
406                             this.log("socket reopen, key management problem: ", arg17);
407                             break label81;
408                         }
409                     }
410 
411                     HttpProcessor processor = this.createProcessor();
412                     if (processor == null) {
413                         try {
414                             this.log(this.sm.getString("httpConnector.noProcessor"));
415                             socket1.close();
416                         } catch (IOException arg18) {
417                             ;
418                         }
419                         continue;
420                     }
421 
422                     processor.assign(socket1);
423                     continue;
424                 }
425             }
426 
427             socket = this.threadSync;
428             synchronized (socket) {
429                 this.threadSync.notifyAll();
430                 return;
431             }
432         }
433     }
434 
435     private void threadStart() {
436         this.log(this.sm.getString("httpConnector.starting"));
437         this.thread = new Thread(this, this.threadName);
438         this.thread.setDaemon(true);
439         this.thread.start();
440     }
441 
442     private void threadStop() {
443         this.log(this.sm.getString("httpConnector.stopping"));
444         this.stopped = true;
445 
446         try {
447             this.threadSync.wait(5000L);
448         } catch (InterruptedException arg1) {
449             ;
450         }
451 
452         this.thread = null;
453     }
454 
455     public void addLifecycleListener(LifecycleListener listener) {
456         this.lifecycle.addLifecycleListener(listener);
457     }
458 
459     public LifecycleListener[] findLifecycleListeners() {
460         return this.lifecycle.findLifecycleListeners();
461     }
462 
463     public void removeLifecycleListener(LifecycleListener listener) {
464         this.lifecycle.removeLifecycleListener(listener);
465     }
466 
467     public void initialize() throws LifecycleException {
468         if (this.initialized) {
469             throw new LifecycleException(this.sm.getString("httpConnector.alreadyInitialized"));
470         } else {
471             this.initialized = true;
472             Object eRethrow = null;
473 
474             try {
475                 this.serverSocket = this.open();
476             } catch (IOException arg7) {
477                 this.log("httpConnector, io problem: ", arg7);
478                 eRethrow = arg7;
479             } catch (KeyStoreException arg8) {
480                 this.log("httpConnector, keystore problem: ", arg8);
481                 eRethrow = arg8;
482             } catch (NoSuchAlgorithmException arg9) {
483                 this.log("httpConnector, keystore algorithm problem: ", arg9);
484                 eRethrow = arg9;
485             } catch (CertificateException arg10) {
486                 this.log("httpConnector, certificate problem: ", arg10);
487                 eRethrow = arg10;
488             } catch (UnrecoverableKeyException arg11) {
489                 this.log("httpConnector, unrecoverable key: ", arg11);
490                 eRethrow = arg11;
491             } catch (KeyManagementException arg12) {
492                 this.log("httpConnector, key management problem: ", arg12);
493                 eRethrow = arg12;
494             }
495 
496             if (eRethrow != null) {
497                 throw new LifecycleException(this.threadName + ".open", (Throwable) eRethrow);
498             }
499         }
500     }
501 
502     public void start() throws LifecycleException {
503         if (this.started) {
504             throw new LifecycleException(this.sm.getString("httpConnector.alreadyStarted"));
505         } else {
506             this.threadName = "HttpConnector[" + this.port + "]";
507             this.lifecycle.fireLifecycleEvent("start", (Object) null);
508             this.started = true;
509             this.threadStart();
510 
511             while (this.curProcessors < this.minProcessors
512                     && (this.maxProcessors <= 0 || this.curProcessors < this.maxProcessors)) {
513                 HttpProcessor processor = this.newProcessor();
514                 this.recycle(processor);
515             }
516 
517         }
518     }
519 
520     public void stop() throws LifecycleException {
521         if (!this.started) {
522             throw new LifecycleException(this.sm.getString("httpConnector.notStarted"));
523         } else {
524             this.lifecycle.fireLifecycleEvent("stop", (Object) null);
525             this.started = false;
526 
527             for (int i = this.created.size() - 1; i >= 0; --i) {
528                 HttpProcessor processor = (HttpProcessor) this.created.elementAt(i);
529                 if (processor instanceof Lifecycle) {
530                     try {
531                         processor.stop();
532                     } catch (LifecycleException arg5) {
533                         this.log("HttpConnector.stop", arg5);
534                     }
535                 }
536             }
537 
538             Object arg7 = this.threadSync;
539             synchronized (arg7) {
540                 if (this.serverSocket != null) {
541                     try {
542                         this.serverSocket.close();
543                     } catch (IOException arg4) {
544                         ;
545                     }
546                 }
547 
548                 this.threadStop();
549             }
550 
551             this.serverSocket = null;
552         }
553     }
554 }
代码清单

  代码分析:由于没有main方法,仅从代码无法了解到程序的入口在哪里,现在只需要知道initialize()方法在启动服务器时会被调用,至于该方法执行之前做了什么,忽略!

               

  类关系:(HttpConnetor接口有很多实现类,但是这些都是静态关系,是为实现类下定义,或者是采用一些常见的模版模式来复用代码。这里忽略其他实现类,只关注该类。)

            

     

猜你喜欢

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