Tomcat 绯荤粺鏋舵瀯涓庤璁℃ā寮忥紝绗?一 閮ㄥ垎: 宸ヤ綔鍘熺悊
鍘熸枃鍦板潃锛?a href="http://www.ibm.com/developerworks/cn/java/j-lo-tomcat1/" style="font-size: 12px; line-height: 1.5;">http://www.ibm.com/developerworks/cn/java/j-lo-tomcat1/
聽
杩欎釜鍒嗕负涓や釜閮ㄥ垎鐨勭郴鍒楁枃绔犲皢鐮旂┒ Apache Tomcat 鐨勭郴缁熸灦鏋勪互鍙婂叾杩愮敤鐨勫緢澶氱粡鍏歌璁℃ā寮忋€傛湰鏂囨槸绗?1 閮ㄥ垎锛屽皢涓昏浠?Tomcat 濡備綍鍒嗗彂璇锋眰銆佸浣曞鐞嗗鐢ㄦ埛鍚屾椂璇锋眰锛岃繕鏈夊畠鐨勫绾у鍣ㄦ槸濡備綍鍗忚皟宸ヤ綔鐨勮搴︽潵鍒嗘瀽 Tomcat 鐨勫伐浣滃師鐞嗭紝杩欎篃鏄竴涓?Web 鏈嶅姟鍣ㄩ瑕佽В鍐崇殑鍏抽敭闂銆?/span>
聽
鏈枃浠?Tomcat 5 涓哄熀纭€锛屼篃鍏奸【鏈€鏂扮殑 Tomcat 6 鍜?Tomcat 4銆俆omcat 鐨勫熀鏈璁℃€濊矾鍜屾灦鏋勬槸鍏锋湁涓€瀹氳繛缁€х殑銆?/p>
Tomcat 鎬讳綋缁撴瀯
Tomcat 鐨勭粨鏋勫緢澶嶆潅锛屼絾鏄?Tomcat 涔熼潪甯哥殑妯″潡鍖栵紝鎵惧埌浜?Tomcat 鏈€鏍稿績鐨勬ā鍧楋紝鎮ㄥ氨鎶撲綇浜?Tomcat 鐨勨€滀竷瀵糕€濄€備笅闈㈡槸 Tomcat 鐨勬€讳綋缁撴瀯鍥撅細
鍥?1.Tomcat 鐨勬€讳綋缁撴瀯
浠庝笂鍥句腑鍙互鐪嬪嚭 Tomcat 鐨勫績鑴忔槸涓や釜缁勪欢锛欳onnector 鍜?Container锛屽叧浜庤繖涓や釜缁勪欢灏嗗湪鍚庨潰璇︾粏浠嬬粛銆侰onnector 缁勪欢鏄彲浠ヨ鏇挎崲锛岃繖鏍峰彲浠ユ彁渚涚粰鏈嶅姟鍣ㄨ璁¤€呮洿澶氱殑閫夋嫨锛屽洜涓鸿繖涓粍浠舵槸濡傛閲嶈锛屼笉浠呰窡鏈嶅姟鍣ㄧ殑璁捐鐨勬湰韬紝鑰屼笖鍜屼笉鍚岀殑搴旂敤鍦烘櫙涔熷崄鍒嗙浉鍏筹紝鎵€浠ヤ竴涓?Container 鍙互閫夋嫨瀵瑰簲澶氫釜 Connector銆傚涓?Connector 鍜屼竴涓?Container 灏卞舰鎴愪簡涓€涓?Service锛孲ervice 鐨勬蹇靛ぇ瀹堕兘寰堢啛鎮変簡锛屾湁浜?Service 灏卞彲浠ュ澶栨彁渚涙湇鍔′簡锛屼絾鏄?Service 杩樿涓€涓敓瀛樼殑鐜锛屽繀椤昏鏈変汉鑳藉缁欏ス鐢熷懡銆佹帉鎻″叾鐢熸澶ф潈锛岄偅灏遍潪 Server 鑾睘浜嗐€傛墍浠ユ暣涓?Tomcat 鐨勭敓鍛藉懆鏈熺敱 Server 鎺у埗銆?/p>
浠?Service 浣滀负鈥滃濮烩€?/h3>
鎴戜滑灏?Tomcat 涓?Connector銆丆ontainer 浣滀负涓€涓暣浣撴瘮浣滀竴瀵规儏渚g殑璇濓紝Connector 涓昏璐熻矗瀵瑰浜ゆ祦锛屽彲浠ユ瘮浣滀负 Boy锛孋ontainer 涓昏澶勭悊 Connector 鎺ュ彈鐨勮姹傦紝涓昏鏄鐞嗗唴閮ㄤ簨鍔★紝鍙互姣斾綔涓?Girl銆傞偅涔堣繖涓?Service 灏辨槸杩炴帴杩欏鐢峰コ鐨勭粨濠氳瘉浜嗐€傛槸 Service 灏嗗畠浠繛鎺ュ湪涓€璧凤紝鍏卞悓缁勬垚涓€涓搴€傚綋鐒惰缁勬垚涓€涓搴繕瑕佸緢澶氬叾瀹冪殑鍏冪礌銆?/p>
璇寸櫧浜嗭紝Service 鍙槸鍦?Connector 鍜?Container 澶栭潰澶氬寘涓€灞傦紝鎶婂畠浠粍瑁呭湪涓€璧凤紝鍚戝闈㈡彁渚涙湇鍔★紝涓€涓?Service 鍙互璁剧疆澶氫釜 Connector锛屼絾鏄彧鑳芥湁涓€涓?Container 瀹瑰櫒銆傝繖涓?Service 鎺ュ彛鐨勬柟娉曞垪琛ㄥ涓嬶細
鍥?2. Service 鎺ュ彛
浠?Service 鎺ュ彛涓畾涔夌殑鏂规硶涓彲浠ョ湅鍑猴紝瀹冧富瑕佹槸涓轰簡鍏宠仈 Connector 鍜?Container锛屽悓鏃朵細鍒濆鍖栧畠涓嬮潰鐨勫叾瀹冪粍浠讹紝娉ㄦ剰鎺ュ彛涓畠骞舵病鏈夎瀹氫竴瀹氳鎺у埗瀹冧笅闈㈢殑缁勪欢鐨勭敓鍛藉懆鏈熴€傛墍鏈夌粍浠剁殑鐢熷懡鍛ㄦ湡鍦ㄤ竴涓?Lifecycle 鐨勬帴鍙d腑鎺у埗锛岃繖閲岀敤鍒颁簡涓€涓噸瑕佺殑璁捐妯″紡锛屽叧浜庤繖涓帴鍙e皢鍦ㄥ悗闈粙缁嶃€?/p>
Tomcat 涓?Service 鎺ュ彛鐨勬爣鍑嗗疄鐜扮被鏄?StandardService 瀹冧笉浠呭疄鐜颁簡 Service 鍊熷彛鍚屾椂杩樺疄鐜颁簡 Lifecycle 鎺ュ彛锛岃繖鏍峰畠灏卞彲浠ユ帶鍒跺畠涓嬮潰鐨勭粍浠剁殑鐢熷懡鍛ㄦ湡浜嗐€係tandardService 绫荤粨鏋勫浘濡備笅锛?/p>
鍥?3. StandardService 鐨勭被缁撴瀯鍥?/h5>
浠庝笂鍥句腑鍙互鐪嬪嚭闄や簡 Service 鎺ュ彛鐨勬柟娉曠殑瀹炵幇浠ュ強鎺у埗缁勪欢鐢熷懡鍛ㄦ湡鐨?Lifecycle 鎺ュ彛鐨勫疄鐜帮紝杩樻湁鍑犱釜鏂规硶鏄敤浜庡湪浜嬩欢鐩戝惉鐨勬柟娉曠殑瀹炵幇锛屼笉浠呮槸杩欎釜 Service 缁勪欢锛孴omcat 涓叾瀹冪粍浠朵篃鍚屾牱鏈夎繖鍑犱釜鏂规硶锛岃繖涔熸槸涓€涓吀鍨嬬殑璁捐妯″紡锛屽皢鍦ㄥ悗闈粙缁嶃€?/p>
涓嬮潰鐪嬩竴涓?StandardService 涓富瑕佺殑鍑犱釜鏂规硶瀹炵幇鐨勪唬鐮侊紝涓嬮潰鏄?setContainer 鍜?addConnector 鏂规硶鐨勬簮鐮侊細
娓呭崟 1. StandardService. SetContainer
public void setContainer(Container container) { 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) { ; } } support.firePropertyChange("container", oldContainer, this.container); }
杩欐浠g爜寰堢畝鍗曪紝鍏跺疄灏辨槸鍏堝垽鏂綋鍓嶇殑杩欎釜 Service 鏈夋病鏈夊凡缁忓叧鑱斾簡 Container锛屽鏋滃凡缁忓叧鑱斾簡锛岄偅涔堝幓鎺夎繖涓叧鑱斿叧绯烩€斺€?oldContainer.setService(null)銆傚鏋滆繖涓?oldContainer 宸茬粡琚惎鍔ㄤ簡锛岀粨鏉熷畠鐨勭敓鍛藉懆鏈熴€傜劧鍚庡啀鏇挎崲鏂扮殑鍏宠仈銆佸啀鍒濆鍖栧苟寮€濮嬭繖涓柊鐨?Container 鐨勭敓鍛藉懆鏈熴€傛渶鍚庡皢杩欎釜杩囩▼閫氱煡鎰熷叴瓒g殑浜嬩欢鐩戝惉绋嬪簭銆傝繖閲屽€煎緱娉ㄦ剰鐨勫湴鏂瑰氨鏄紝淇敼 Container 鏃惰灏嗘柊鐨?Container 鍏宠仈鍒版瘡涓?Connector锛岃繕濂?Container 鍜?Connector 娌℃湁鍙屽悜鍏宠仈锛屼笉鐒惰繖涓叧鑱斿叧绯诲皢浼氬緢闅剧淮鎶ゃ€?/p>
娓呭崟 2. StandardService. 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) { ; } } support.firePropertyChange("connector", null, connector); } }
涓婇潰鏄?addConnector 鏂规硶锛岃繖涓柟娉曚篃寰堢畝鍗曪紝棣栧厛鏄缃叧鑱斿叧绯伙紝鐒跺悗鏄垵濮嬪寲宸ヤ綔锛屽紑濮嬫柊鐨勭敓鍛藉懆鏈熴€傝繖閲屽€煎緱涓€鎻愮殑鏄紝娉ㄦ剰 Connector 鐢ㄧ殑鏄暟缁勮€屼笉鏄?List 闆嗗悎锛岃繖涓粠鎬ц兘瑙掑害鑰冭檻鍙互鐞嗚В锛屾湁瓒g殑鏄繖閲岀敤浜嗘暟缁勪絾鏄苟娌℃湁鍚戞垜浠钩甯搁偅鏍凤紝涓€寮€濮嬪氨鍒嗛厤涓€涓浐瀹氬ぇ灏忕殑鏁扮粍锛屽畠杩欓噷鐨勫疄鐜版満鍒舵槸锛氶噸鏂板垱寤轰竴涓綋鍓嶅ぇ灏忕殑鏁扮粍瀵硅薄锛岀劧鍚庡皢鍘熸潵鐨勬暟缁勫璞?copy 鍒版柊鐨勬暟缁勪腑锛岃繖绉嶆柟寮忓疄鐜颁簡绫讳技鐨勫姩鎬佹暟缁勭殑鍔熻兘锛岃繖绉嶅疄鐜版柟寮忥紝鍊煎緱鎴戜滑浠ュ悗鎷挎潵鍊熼壌銆?/p>
鏈€鏂扮殑 Tomcat6 涓?StandardService 涔熷熀鏈病鏈夊彉鍖栵紝浣嗘槸浠?Tomcat5 寮€濮?Service銆丼erver 鍜屽鍣ㄧ被閮界户鎵夸簡 MBeanRegistration 鎺ュ彛锛孧beans 鐨勭鐞嗘洿鍔犲悎鐞嗐€?/p>
浠?Server 涓衡€滃眳鈥?/h3>
鍓嶉潰璇翠竴瀵规儏渚e洜涓?Service 鑰屾垚涓轰竴瀵瑰か濡伙紝鏈変簡鑳藉缁勬垚涓€涓搴殑鍩烘湰鏉′欢锛屼絾鏄畠浠繕瑕佹湁涓疄浣撶殑瀹讹紝杩欐槸瀹冧滑鍦ㄧぞ浼氫笂鐢熷瓨涔嬫湰锛屾湁浜嗗瀹冧滑灏卞彲浠ュ畨蹇冪殑涓轰汉姘戞湇鍔′簡锛屼竴璧蜂负绀句細鍒涢€犺储瀵屻€?/p>
Server 瑕佸畬鎴愮殑浠诲姟寰堢畝鍗曪紝灏辨槸瑕佽兘澶熸彁渚涗竴涓帴鍙h鍏跺畠绋嬪簭鑳藉璁块棶鍒拌繖涓?Service 闆嗗悎銆佸悓鏃惰缁存姢瀹冩墍鍖呭惈鐨勬墍鏈?Service 鐨勭敓鍛藉懆鏈燂紝鍖呮嫭濡備綍鍒濆鍖栥€佸浣曠粨鏉熸湇鍔°€佸浣曟壘鍒板埆浜鸿璁块棶鐨?Service銆傝繕鏈夊叾瀹冪殑涓€浜涙瑕佺殑浠诲姟锛屽鎮ㄤ綇鍦ㄨ繖涓湴鏂硅鍚戝綋鍦版斂搴滃幓鐧昏鍟娿€佸彲鑳借繕鏈夎閰嶅悎褰撳湴鍏畨鏈哄叧鏃ュ父鐨勫畨鍏ㄦ鏌ヤ粈涔堢殑銆?/p>
Server 鐨勭被缁撴瀯鍥惧涓嬶細
鍥?4. Server 鐨勭被缁撴瀯鍥?/h5>
瀹冪殑鏍囧噯瀹炵幇绫?StandardServer 瀹炵幇浜嗕笂闈㈣繖浜涙柟娉曪紝鍚屾椂涔熷疄鐜颁簡 Lifecycle銆丮beanRegistration 涓や釜鎺ュ彛鐨勬墍鏈夋柟娉曪紝涓嬮潰涓昏鐪嬩竴涓?StandardServer 閲嶈鐨勪竴涓柟娉?addService 鐨勫疄鐜帮細
娓呭崟 3. StandardServer.addService
public void addService(Service service) { service.setServer(this); synchronized (services) { Service results[] = new Service[services.length + 1]; System.arraycopy(services, 0, results, 0, services.length); results[services.length] = service; services = results; if (initialized) { try { service.initialize(); } catch (LifecycleException e) { e.printStackTrace(System.err); } } if (started && (service instanceof Lifecycle)) { try { ((Lifecycle) service).start(); } catch (LifecycleException e) { ; } } support.firePropertyChange("service", null, service); } }
浠庝笂闈㈢涓€鍙ュ氨鐭ラ亾浜?Service 鍜?Server 鏄浉浜掑叧鑱旂殑锛孲erver 涔熸槸鍜?Service 绠$悊 Connector 涓€鏍风鐞嗗畠锛屼篃鏄皢 Service 鏀惧湪涓€涓暟缁勪腑锛屽悗闈㈤儴鍒嗙殑浠g爜涔熸槸绠$悊杩欎釜鏂板姞杩涙潵鐨?Service 鐨勭敓鍛藉懆鏈熴€俆omcat6 涓篃鏄病鏈変粈涔堝彉鍖栫殑銆?/p>
缁勪欢鐨勭敓鍛界嚎鈥淟ifecycle鈥?/h3>
鍓嶉潰涓€鐩村湪璇?Service 鍜?Server 绠$悊瀹冧笅闈㈢粍浠剁殑鐢熷懡鍛ㄦ湡锛岄偅瀹冧滑鏄浣曠鐞嗙殑鍛紵
Tomcat 涓粍浠剁殑鐢熷懡鍛ㄦ湡鏄€氳繃 Lifecycle 鎺ュ彛鏉ユ帶鍒剁殑锛岀粍浠跺彧瑕佺户鎵胯繖涓帴鍙e苟瀹炵幇鍏朵腑鐨勬柟娉曞氨鍙互缁熶竴琚嫢鏈夊畠鐨勭粍浠舵帶鍒朵簡锛岃繖鏍蜂竴灞備竴灞傜殑鐩村埌涓€涓渶楂樼骇鐨勭粍浠跺氨鍙互鎺у埗 Tomcat 涓墍鏈夌粍浠剁殑鐢熷懡鍛ㄦ湡锛岃繖涓渶楂樼殑缁勪欢灏辨槸 Server锛岃€屾帶鍒?Server 鐨勬槸 Startup锛屼篃灏辨槸鎮ㄥ惎鍔ㄥ拰鍏抽棴 Tomcat銆?/p>
涓嬮潰鏄?Lifecycle 鎺ュ彛鐨勭被缁撴瀯鍥撅細
鍥?5. Lifecycle 绫荤粨鏋勫浘
闄や簡鎺у埗鐢熷懡鍛ㄦ湡鐨?Start 鍜?Stop 鏂规硶澶栬繕鏈変竴涓洃鍚満鍒讹紝鍦ㄧ敓鍛藉懆鏈熷紑濮嬪拰缁撴潫鐨勬椂鍊欏仛涓€浜涢澶栫殑鎿嶄綔銆傝繖涓満鍒跺湪鍏跺畠鐨勬鏋朵腑涔熻浣跨敤锛屽鍦?Spring 涓€傚叧浜庤繖涓璁℃ā寮忎細鍦ㄥ悗闈粙缁嶃€?/p>
Lifecycle 鎺ュ彛鐨勬柟娉曠殑瀹炵幇閮藉湪鍏跺畠缁勪欢涓紝灏卞儚鍓嶉潰涓鐨勶紝缁勪欢鐨勭敓鍛藉懆鏈熺敱鍖呭惈瀹冪殑鐖剁粍浠舵帶鍒讹紝鎵€浠ュ畠鐨?Start 鏂规硶鑷劧灏辨槸璋冪敤瀹冧笅闈㈢殑缁勪欢鐨?Start 鏂规硶锛孲top 鏂规硶涔熸槸涓€鏍枫€傚鍦?Server 涓?Start 鏂规硶灏变細璋冪敤 Service 缁勪欢鐨?Start 鏂规硶锛孲erver 鐨?Start 鏂规硶浠g爜濡備笅锛?/p>
娓呭崟 4. StandardServer.Start
public void start() throws LifecycleException { if (started) { log.debug(sm.getString("standardServer.start.started")); return; } lifecycle.fireLifecycleEvent(BEFORE_START_EVENT, null); lifecycle.fireLifecycleEvent(START_EVENT, null); started = true; synchronized (services) { for (int i = 0; i < services.length; i++) { if (services[i] instanceof Lifecycle) ((Lifecycle) services[i]).start(); } } lifecycle.fireLifecycleEvent(AFTER_START_EVENT, null); }
鐩戝惉鐨勪唬鐮佷細鍖呭洿 Service 缁勪欢鐨勫惎鍔ㄨ繃绋嬶紝灏辨槸绠€鍗曠殑寰幆鍚姩鎵€鏈?Service 缁勪欢鐨?Start 鏂规硶锛屼絾鏄墍鏈?Service 蹇呴』瑕佸疄鐜?Lifecycle 鎺ュ彛锛岃繖鏍峰仛浼氭洿鍔犵伒娲汇€?/p>
Server 鐨?Stop 鏂规硶浠g爜濡備笅锛?/p>
娓呭崟 5. StandardServer.Stop
public void stop() throws LifecycleException { if (!started) return; lifecycle.fireLifecycleEvent(BEFORE_STOP_EVENT, null); lifecycle.fireLifecycleEvent(STOP_EVENT, null); started = false; for (int i = 0; i < services.length; i++) { if (services[i] instanceof Lifecycle) ((Lifecycle) services[i]).stop(); } lifecycle.fireLifecycleEvent(AFTER_STOP_EVENT, null); }
瀹冩墍瑕佸仛鐨勪簨鎯呬篃鍜?Start 鏂规硶宸笉澶氥€?/p>
Connector 缁勪欢
Connector 缁勪欢鏄?Tomcat 涓袱涓牳蹇冪粍浠朵箣涓€锛屽畠鐨勪富瑕佷换鍔℃槸璐熻矗鎺ユ敹娴忚鍣ㄧ殑鍙戣繃鏉ョ殑 tcp 杩炴帴璇锋眰锛屽垱寤轰竴涓?Request 鍜?Response 瀵硅薄鍒嗗埆鐢ㄤ簬鍜岃姹傜浜ゆ崲鏁版嵁锛岀劧鍚庝細浜х敓涓€涓嚎绋嬫潵澶勭悊杩欎釜璇锋眰骞舵妸浜х敓鐨?Request 鍜?Response 瀵硅薄浼犵粰澶勭悊杩欎釜璇锋眰鐨勭嚎绋嬶紝澶勭悊杩欎釜璇锋眰鐨勭嚎绋嬪氨鏄?Container 缁勪欢瑕佸仛鐨勪簨浜嗐€?/p>
鐢变簬杩欎釜杩囩▼姣旇緝澶嶆潅锛屽ぇ浣撶殑娴佺▼鍙互鐢ㄤ笅闈㈢殑椤哄簭鍥炬潵瑙i噴锛?/p>
鍥?6. Connector 澶勭悊涓€娆¤姹傞『搴忓浘
锛?a target="_blank" href="http://www.ibm.com/developerworks/cn/java/j-lo-tomcat1/origin_image006.png" style="margin: 0px; padding: 0px; border: 0px; font-size: inherit; vertical-align: baseline; color: #745285;">鏌ョ湅娓呮櫚澶у浘锛?/p>
Tomcat5 涓粯璁ょ殑 Connector 鏄?Coyote锛岃繖涓?Connector 鏄彲浠ラ€夋嫨鏇挎崲鐨勩€侰onnector 鏈€閲嶈鐨勫姛鑳藉氨鏄帴鏀惰繛鎺ヨ姹傜劧鍚庡垎閰嶇嚎绋嬭 Container 鏉ュ鐞嗚繖涓姹傦紝鎵€浠ヨ繖蹇呯劧鏄绾跨▼鐨勶紝澶氱嚎绋嬬殑澶勭悊鏄?Connector 璁捐鐨勬牳蹇冦€俆omcat5 灏嗚繖涓繃绋嬫洿鍔犵粏鍖栵紝瀹冨皢 Connector 鍒掑垎鎴?Connector銆丳rocessor銆丳rotocol, 鍙﹀ Coyote 涔熷畾涔夎嚜宸辩殑 Request 鍜?Response 瀵硅薄銆?/p>
涓嬮潰涓昏鐪嬩竴涓?Tomcat 涓浣曞鐞嗗绾跨▼鐨勮繛鎺ヨ姹傦紝鍏堢湅涓€涓?Connector 鐨勪富瑕佺被鍥撅細
鍥?7. Connector 鐨勪富瑕佺被鍥?/h5>
锛?a target="_blank" href="http://www.ibm.com/developerworks/cn/java/j-lo-tomcat1/origin_image007.png" style="margin: 0px; padding: 0px; border: 0px; font-size: inherit; vertical-align: baseline; color: #745285;">鏌ョ湅娓呮櫚澶у浘锛?/p>
鐪嬩竴涓?HttpConnector 鐨?Start 鏂规硶锛?/p>
娓呭崟 6. HttpConnector.Start
public void start() throws LifecycleException { if (started) throw new LifecycleException (sm.getString("httpConnector.alreadyStarted")); threadName = "HttpConnector[" + port + "]"; lifecycle.fireLifecycleEvent(START_EVENT, null); started = true; threadStart(); while (curProcessors < minProcessors) { if ((maxProcessors > 0) && (curProcessors >= maxProcessors)) break; HttpProcessor processor = newProcessor(); recycle(processor); } }
threadStart() 鎵ц灏变細杩涘叆绛夊緟璇锋眰鐨勭姸鎬侊紝鐩村埌涓€涓柊鐨勮姹傚埌鏉ユ墠浼氭縺娲诲畠缁х画鎵ц锛岃繖涓縺娲绘槸鍦?HttpProcessor 鐨?assign 鏂规硶涓紝杩欎釜鏂规硶鏄唬鐮佸涓嬄?code style="margin: 0px; padding: 0px; border: 0px; font-size: 0.95em !important; vertical-align: baseline; font-family: 'Andale Mono', 'Lucida Console', Monaco, Liberation, fixed, monospace; line-height: 1.5em; color: #000000 !important;">锛?/code>
娓呭崟 7. HttpProcessor.assign
synchronized void assign(Socket socket) { while (available) { try { wait(); } catch (InterruptedException e) { } } this.socket = socket; available = true; notifyAll(); if ((debug >= 1) && (socket != null)) log(" An incoming request is being assigned"); }
鍒涘缓 HttpProcessor 瀵硅薄鏄細鎶?available 璁句负 false锛屾墍浠ュ綋璇锋眰鍒版潵鏃朵笉浼氳繘鍏?while 寰幆锛屽皢璇锋眰鐨?socket 璧嬬粰褰撴湡澶勭悊鐨?socket锛屽苟灏?available 璁句负 true锛屽綋 available 璁句负 true 鏄?HttpProcessor 鐨?run 鏂规硶灏嗚婵€娲伙紝鎺ヤ笅鍘诲皢浼氬鐞嗚繖娆¤姹傘€?/p>
Run 鏂规硶浠g爜濡備笅锛?/p>
娓呭崟 8. HttpProcessor.Run
public void run() { while (!stopped) { Socket socket = await(); if (socket == null) continue; try { process(socket); } catch (Throwable t) { log("process.invoke", t); } connector.recycle(this); } synchronized (threadSync) { threadSync.notifyAll(); } }
瑙f瀽 socket 鐨勮繃绋嬪湪 process 鏂规硶涓紝process 鏂规硶鐨勪唬鐮佺墖娈靛涓嬶細
娓呭崟 9. HttpProcessor.process
private void process(Socket socket) { boolean ok = true; boolean finishResponse = true; SocketInputStream input = null; OutputStream output = null; try { input = new SocketInputStream(socket.getInputStream(),connector.getBufferSize()); } catch (Exception e) { log("process.create", e); ok = false; } keepAlive = true; while (!stopped && ok && keepAlive) { finishResponse = true; try { request.setStream(input); request.setResponse(response); output = socket.getOutputStream(); response.setStream(output); response.setRequest(request); ((HttpServletResponse) response.getResponse()) .setHeader("Server", SERVER_INFO); } catch (Exception e) { log("process.create", e); ok = false; } try { if (ok) { parseConnection(socket); parseRequest(input, output); if (!request.getRequest().getProtocol().startsWith("HTTP/0")) parseHeaders(input); if (http11) { ackRequest(output); if (connector.isChunkingAllowed()) response.setAllowChunking(true); } } 銆傘€傘€傘€傘€傘€? try { ((HttpServletResponse) response).setHeader ("Date", FastHttpDateFormat.getCurrentDate()); if (ok) { connector.getContainer().invoke(request, response); } 銆傘€傘€傘€傘€傘€? } try { shutdownInput(input); socket.close(); } catch (IOException e) { ; } catch (Throwable e) { log("process.invoke", e); } socket = null; }
褰?Connector 灏?socket 杩炴帴灏佽鎴?request 鍜?response 瀵硅薄鍚庢帴涓嬫潵鐨勪簨鎯呭氨浜ょ粰 Container 鏉ュ鐞嗕簡銆?/p>
Servlet 瀹瑰櫒鈥淐ontainer鈥?/h2>
Container 鏄鍣ㄧ殑鐖舵帴鍙o紝鎵€鏈夊瓙瀹瑰櫒閮藉繀椤诲疄鐜拌繖涓帴鍙o紝Container 瀹瑰櫒鐨勮璁$敤鐨勬槸鍏稿瀷鐨勮矗浠婚摼鐨勮璁℃ā寮忥紝瀹冩湁鍥涗釜瀛愬鍣ㄧ粍浠舵瀯鎴愶紝鍒嗗埆鏄細Engine銆丠ost銆丆ontext銆乄rapper锛岃繖鍥涗釜缁勪欢涓嶆槸骞宠鐨勶紝鑰屾槸鐖跺瓙鍏崇郴锛孍ngine 鍖呭惈 Host,Host 鍖呭惈 Context锛孋ontext 鍖呭惈 Wrapper銆傞€氬父涓€涓?Servlet class 瀵瑰簲涓€涓?Wrapper锛屽鏋滄湁澶氫釜 Servlet 灏卞彲浠ュ畾涔夊涓?Wrapper锛屽鏋滄湁澶氫釜 Wrapper 灏辫瀹氫箟涓€涓洿楂樼殑 Container 浜嗭紝濡?Context锛孋ontext 閫氬父灏辨槸瀵瑰簲涓嬮潰杩欎釜閰嶇疆锛?/p>
娓呭崟 10. Server.xml
<Context path="/library" docBase="D:\projects\library\deploy\target\library.war" reloadable="true" />
瀹瑰櫒鐨勬€讳綋璁捐
Context 杩樺彲浠ュ畾涔夊湪鐖跺鍣?Host 涓紝Host 涓嶆槸蹇呴』鐨勶紝浣嗘槸瑕佽繍琛?war 绋嬪簭锛屽氨蹇呴』瑕?Host锛屽洜涓?war 涓繀鏈?web.xml 鏂囦欢锛岃繖涓枃浠剁殑瑙f瀽灏遍渶瑕?Host 浜嗭紝濡傛灉瑕佹湁澶氫釜 Host 灏辫瀹氫箟涓€涓?top 瀹瑰櫒 Engine 浜嗐€傝€?Engine 娌℃湁鐖跺鍣ㄤ簡锛屼竴涓?Engine 浠h〃涓€涓畬鏁寸殑 Servlet 寮曟搸銆?/p>
閭d箞杩欎簺瀹瑰櫒鏄浣曞崗鍚屽伐浣滅殑鍛紵鍏堢湅涓€涓嬪畠浠箣闂寸殑鍏崇郴鍥撅細
鍥?8. 鍥涗釜瀹瑰櫒鐨勫叧绯诲浘
锛?a target="_blank" href="http://www.ibm.com/developerworks/cn/java/j-lo-tomcat1/origin_image008.png" style="margin: 0px; padding: 0px; border: 0px; font-size: inherit; vertical-align: baseline; color: #745285;">鏌ョ湅娓呮櫚澶у浘锛?/p>
褰?Connector 鎺ュ彈鍒颁竴涓繛鎺ヨ姹傛椂锛屽皢璇锋眰浜ょ粰 Container锛孋ontainer 鏄浣曞鐞嗚繖涓姹傜殑锛熻繖鍥涗釜缁勪欢鏄€庝箞鍒嗗伐鐨勶紝鎬庝箞鎶婅姹備紶缁欑壒瀹氱殑瀛愬鍣ㄧ殑鍛紵鍙堟槸濡備綍灏嗘渶缁堢殑璇锋眰浜ょ粰 Servlet 澶勭悊銆備笅闈㈡槸杩欎釜杩囩▼鐨勬椂搴忓浘锛?/p>
鍥?9. Engine 鍜?Host 澶勭悊璇锋眰鐨勬椂搴忓浘
锛?a target="_blank" href="http://www.ibm.com/developerworks/cn/java/j-lo-tomcat1/origin_image009.png" style="margin: 0px; padding: 0px; border: 0px; font-size: inherit; vertical-align: baseline; color: #745285;">鏌ョ湅娓呮櫚澶у浘锛?/p>
杩欓噷鐪嬪埌浜?Valve 鏄笉鏄緢鐔熸倝锛屾病閿?Valve 鐨勮璁″湪鍏朵粬妗嗘灦涓篃鏈夌敤鐨勶紝鍚屾牱 Pipeline 鐨勫師鐞嗕篃鍩烘湰鏄浉浼肩殑锛屽畠鏄竴涓閬擄紝Engine 鍜?Host 閮戒細鎵ц杩欎釜 Pipeline锛屾偍鍙互鍦ㄨ繖涓閬撲笂澧炲姞浠绘剰鐨?Valve锛孴omcat 浼氭尐涓墽琛岃繖浜?Valve锛岃€屼笖鍥涗釜缁勪欢閮戒細鏈夎嚜宸辩殑涓€濂?Valve 闆嗗悎銆傛偍鎬庝箞鎵嶈兘瀹氫箟鑷繁鐨?Valve 鍛紵鍦?server.xml 鏂囦欢涓彲浠ユ坊鍔狅紝濡傜粰 Engine 鍜?Host 澧炲姞涓€涓?Valve 濡備笅锛?/p>
娓呭崟 11. Server.xml
<Engine defaultHost="localhost" name="Catalina"> <Valve className="org.apache.catalina.valves.RequestDumperValve"/> 鈥︹€︹€? <Host appBase="webapps" autoDeploy="true" name="localhost" unpackWARs="true" xmlNamespaceAware="false" xmlValidation="false"> <Valve className="org.apache.catalina.valves.FastCommonAccessLogValve" directory="logs" prefix="localhost_access_log." suffix=".txt" pattern="common" resolveHosts="false"/> 鈥︹€︹€︹€? </Host> </Engine>
StandardEngineValve 鍜?StandardHostValve 鏄?Engine 鍜?Host 鐨勯粯璁ょ殑 Valve锛屽畠浠槸鏈€鍚庝竴涓?Valve 璐熻矗灏嗚姹備紶缁欏畠浠殑瀛愬鍣紝浠ョ户缁線涓嬫墽琛屻€?/p>
鍓嶉潰鏄?Engine 鍜?Host 瀹瑰櫒鐨勮姹傝繃绋嬶紝涓嬮潰鐪?Context 鍜?Wrapper 瀹瑰櫒鏃跺浣曞鐞嗚姹傜殑銆備笅闈㈡槸澶勭悊璇锋眰鐨勬椂搴忓浘锛?/p>
鍥?10. Context 鍜?wrapper 鐨勫鐞嗚姹傛椂搴忓浘
锛?a target="_blank" href="http://www.ibm.com/developerworks/cn/java/j-lo-tomcat1/origin_image010.png" style="margin: 0px; padding: 0px; border: 0px; font-size: inherit; vertical-align: baseline; color: #745285;">鏌ョ湅娓呮櫚澶у浘锛?/p>
浠?Tomcat5 寮€濮嬶紝瀛愬鍣ㄧ殑璺敱鏀惧湪浜?request 涓紝request 涓繚瀛樹簡褰撳墠璇锋眰姝e湪澶勭悊鐨?Host銆丆ontext 鍜?wrapper銆?/p>
Engine 瀹瑰櫒
Engine 瀹瑰櫒姣旇緝绠€鍗曪紝瀹冨彧瀹氫箟浜嗕竴浜涘熀鏈殑鍏宠仈鍏崇郴锛屾帴鍙g被鍥惧涓嬶細
鍥?11. Engine 鎺ュ彛鐨勭被缁撴瀯
瀹冪殑鏍囧噯瀹炵幇绫绘槸 StandardEngine锛岃繖涓被娉ㄦ剰涓€鐐瑰氨鏄?Engine 娌℃湁鐖跺鍣ㄤ簡锛屽鏋滆皟鐢?setParent 鏂规硶鏃跺皢浼氭姤閿欍€傛坊鍔犲瓙瀹瑰櫒涔熷彧鑳芥槸 Host 绫诲瀷鐨勶紝浠g爜濡備笅锛?/p>
娓呭崟 12. StandardEngine. addChild
public void addChild(Container child) { if (!(child instanceof Host)) throw new IllegalArgumentException (sm.getString("standardEngine.notHost")); super.addChild(child); } public void setParent(Container container) { throw new IllegalArgumentException (sm.getString("standardEngine.notParent")); }
瀹冪殑鍒濆鍖栨柟娉曚篃灏辨槸鍒濆鍖栧拰瀹冪浉鍏宠仈鐨勭粍浠讹紝浠ュ強涓€浜涗簨浠剁殑鐩戝惉銆?/p>
Host 瀹瑰櫒
Host 鏄?Engine 鐨勫瓧瀹瑰櫒锛屼竴涓?Host 鍦?Engine 涓唬琛ㄤ竴涓櫄鎷熶富鏈猴紝杩欎釜铏氭嫙涓绘満鐨勪綔鐢ㄥ氨鏄繍琛屽涓簲鐢紝瀹冭礋璐e畨瑁呭拰灞曞紑杩欎簺搴旂敤锛屽苟涓旀爣璇嗚繖涓簲鐢ㄤ互渚胯兘澶熷尯鍒嗗畠浠€傚畠鐨勫瓙瀹瑰櫒閫氬父鏄?Context锛屽畠闄や簡鍏宠仈瀛愬鍣ㄥ锛岃繕鏈夊氨鏄繚瀛樹竴涓富鏈哄簲璇ユ湁鐨勪俊鎭€?/p>
涓嬮潰鏄拰 Host 鐩稿叧鐨勭被鍏宠仈鍥撅細
鍥?12. Host 鐩稿叧鐨勭被鍥?/h5>
锛?a target="_blank" href="http://www.ibm.com/developerworks/cn/java/j-lo-tomcat1/origin_image012.png" style="margin: 0px; padding: 0px; border: 0px; font-size: inherit; vertical-align: baseline; color: #745285;">鏌ョ湅娓呮櫚澶у浘锛?/p>
浠庝笂鍥句腑鍙互鐪嬪嚭闄や簡鎵€鏈夊鍣ㄩ兘缁ф壙鐨?ContainerBase 澶栵紝StandardHost 杩樺疄鐜颁簡 Deployer 鎺ュ彛锛屼笂鍥炬竻妤氱殑鍒楀嚭浜嗚繖涓帴鍙g殑涓昏鏂规硶锛岃繖浜涙柟娉曢兘鏄畨瑁呫€佸睍寮€銆佸惎鍔ㄥ拰缁撴潫姣忎釜 web application銆?/p>
Deployer 鎺ュ彛鐨勫疄鐜版槸 StandardHostDeployer锛岃繖涓被瀹炵幇浜嗙殑鏈€瑕佺殑鍑犱釜鏂规硶锛孒ost 鍙互璋冪敤杩欎簺鏂规硶瀹屾垚搴旂敤鐨勯儴缃茬瓑銆?/p>
Context 瀹瑰櫒
Context 浠h〃 Servlet 鐨?Context锛屽畠鍏峰浜?Servlet 杩愯鐨勫熀鏈幆澧冿紝鐞嗚涓婂彧瑕佹湁 Context 灏辫兘杩愯 Servlet 浜嗐€傜畝鍗曠殑 Tomcat 鍙互娌℃湁 Engine 鍜?Host銆?/p>
Context 鏈€閲嶈鐨勫姛鑳藉氨鏄鐞嗗畠閲岄潰鐨?Servlet 瀹炰緥锛孲ervlet 瀹炰緥鍦?Context 涓槸浠?Wrapper 鍑虹幇鐨勶紝杩樻湁涓€鐐瑰氨鏄?Context 濡備綍鎵嶈兘鎵惧埌姝g‘鐨?Servlet 鏉ユ墽琛屽畠鍛紵 Tomcat5 浠ュ墠鏄€氳繃涓€涓?Mapper 绫绘潵绠$悊鐨勶紝Tomcat5 浠ュ悗杩欎釜鍔熻兘琚Щ鍒颁簡 request 涓紝鍦ㄥ墠闈㈢殑鏃跺簭鍥句腑灏卞彲浠ュ彂鐜拌幏鍙栧瓙瀹瑰櫒閮芥槸閫氳繃 request 鏉ュ垎閰嶇殑銆?/p>
Context 鍑嗗 Servlet 鐨勮繍琛岀幆澧冩槸鍦?Start 鏂规硶寮€濮嬬殑锛岃繖涓柟娉曠殑浠g爜鐗囨濡備笅锛?/p>
娓呭崟 13. StandardContext.start
public synchronized void start() throws LifecycleException { 鈥︹€︹€? if( !initialized ) { try { init(); } catch( Exception ex ) { throw new LifecycleException("Error initializaing ", ex); } } 鈥︹€︹€? lifecycle.fireLifecycleEvent(BEFORE_START_EVENT, null); setAvailable(false); setConfigured(false); boolean ok = true; File configBase = getConfigBase(); if (configBase != null) { if (getConfigFile() == null) { File file = new File(configBase, getDefaultConfigFile()); setConfigFile(file.getPath()); try { File appBaseFile = new File(getAppBase()); if (!appBaseFile.isAbsolute()) { appBaseFile = new File(engineBase(), getAppBase()); } String appBase = appBaseFile.getCanonicalPath(); String basePath = (new File(getBasePath())).getCanonicalPath(); if (!basePath.startsWith(appBase)) { Server server = ServerFactory.getServer(); ((StandardServer) server).storeContext(this); } } catch (Exception e) { log.warn("Error storing config file", e); } } else { try { String canConfigFile = (new File(getConfigFile())).getCanonicalPath(); if (!canConfigFile.startsWith (configBase.getCanonicalPath())) { File file = new File(configBase, getDefaultConfigFile()); if (copy(new File(canConfigFile), file)) { setConfigFile(file.getPath()); } } } catch (Exception e) { log.warn("Error setting config file", e); } } } 鈥︹€︹€? Container children[] = findChildren(); for (int i = 0; i < children.length; i++) { if (children[i] instanceof Lifecycle) ((Lifecycle) children[i]).start(); } if (pipeline instanceof Lifecycle) ((Lifecycle) pipeline).start(); 鈥︹€︹€? }
瀹冧富瑕佹槸璁剧疆鍚勭璧勬簮灞炴€у拰绠$悊缁勪欢锛岃繕鏈夐潪甯搁噸瑕佺殑灏辨槸鍚姩瀛愬鍣ㄥ拰 Pipeline銆?/p>
鎴戜滑鐭ラ亾 Context 鐨勯厤缃枃浠朵腑鏈変釜 reloadable 灞炴€э紝濡備笅闈㈤厤缃細
娓呭崟 14. Server.xml
<Context path="/library" docBase="D:\projects\library\deploy\target\library.war" reloadable="true" />
褰撹繖涓?reloadable 璁句负 true 鏃讹紝war 琚慨鏀瑰悗 Tomcat 浼氳嚜鍔ㄧ殑閲嶆柊鍔犺浇杩欎釜搴旂敤銆傚浣曞仛鍒拌繖鐐圭殑鍛?? 杩欎釜鍔熻兘鏄湪 StandardContext 鐨?backgroundProcess 鏂规硶涓疄鐜扮殑锛岃繖涓柟娉曠殑浠g爜濡備笅锛?/p>
娓呭崟 15. StandardContext. backgroundProcess
public void backgroundProcess() { if (!started) return; count = (count + 1) % managerChecksFrequency; if ((getManager() != null) && (count == 0)) { try { getManager().backgroundProcess(); } catch ( Exception x ) { log.warn("Unable to perform background process on manager",x); } } if (getLoader() != null) { if (reloadable && (getLoader().modified())) { try { Thread.currentThread().setContextClassLoader (StandardContext.class.getClassLoader()); reload(); } finally { if (getLoader() != null) { Thread.currentThread().setContextClassLoader (getLoader().getClassLoader()); } } } if (getLoader() instanceof WebappLoader) { ((WebappLoader) getLoader()).closeJARs(false); } } }
瀹冧細璋冪敤 reload 鏂规硶锛岃€?reload 鏂规硶浼氬厛璋冪敤 stop 鏂规硶鐒跺悗鍐嶈皟鐢?Start 鏂规硶锛屽畬鎴?Context 鐨勪竴娆¢噸鏂板姞杞姐€傚彲浠ョ湅鍑烘墽琛?reload 鏂规硶鐨勬潯浠舵槸 reloadable 涓?true 鍜屽簲鐢ㄨ淇敼锛岄偅涔堣繖涓?backgroundProcess 鏂规硶鏄€庝箞琚皟鐢ㄧ殑鍛紵
杩欎釜鏂规硶鏄湪 ContainerBase 绫讳腑瀹氫箟鐨勫唴閮ㄧ被 ContainerBackgroundProcessor 琚懆鏈熻皟鐢ㄧ殑锛岃繖涓被鏄繍琛屽湪涓€涓悗鍙扮嚎绋嬩腑锛屽畠浼氬懆鏈熺殑鎵ц run 鏂规硶锛屽畠鐨?run 鏂规硶浼氬懆鏈熻皟鐢ㄦ墍鏈夊鍣ㄧ殑 backgroundProcess 鏂规硶锛屽洜涓烘墍鏈夊鍣ㄩ兘浼氱户鎵?ContainerBase 绫伙紝鎵€浠ユ墍鏈夊鍣ㄩ兘鑳藉鍦?backgroundProcess 鏂规硶涓畾涔夊懆鏈熸墽琛岀殑浜嬩欢銆?/p>
Wrapper 瀹瑰櫒
Wrapper 浠h〃涓€涓?Servlet锛屽畠璐熻矗绠$悊涓€涓?Servlet锛屽寘鎷殑 Servlet 鐨勮杞姐€佸垵濮嬪寲銆佹墽琛屼互鍙婅祫婧愬洖鏀躲€俉rapper 鏄渶搴曞眰鐨勫鍣紝瀹冩病鏈夊瓙瀹瑰櫒浜嗭紝鎵€浠ヨ皟鐢ㄥ畠鐨?addChild 灏嗕細鎶ラ敊銆?/p>
Wrapper 鐨勫疄鐜扮被鏄?StandardWrapper锛孲tandardWrapper 杩樺疄鐜颁簡鎷ユ湁涓€涓?Servlet 鍒濆鍖栦俊鎭殑 ServletConfig锛岀敱姝ょ湅鍑?StandardWrapper 灏嗙洿鎺ュ拰 Servlet 鐨勫悇绉嶄俊鎭墦浜ら亾銆?/p>
涓嬮潰鐪嬩竴涓嬮潪甯搁噸瑕佺殑涓€涓柟娉?loadServlet锛屼唬鐮佺墖娈靛涓嬶細
娓呭崟 16. StandardWrapper.loadServlet
public synchronized Servlet loadServlet() throws ServletException { 鈥︹€︹€? Servlet servlet; try { 鈥︹€︹€? ClassLoader classLoader = loader.getClassLoader(); 鈥︹€︹€? Class classClass = null; 鈥︹€︹€? servlet = (Servlet) classClass.newInstance(); if ((servlet instanceof ContainerServlet) && (isContainerProvidedServlet(actualClass) || ((Context)getParent()).getPrivileged() )) { ((ContainerServlet) servlet).setWrapper(this); } classLoadTime=(int) (System.currentTimeMillis() -t1); try { instanceSupport.fireInstanceEvent(InstanceEvent.BEFORE_INIT_EVENT,servlet); if( System.getSecurityManager() != null) { Class[] classType = new Class[]{ServletConfig.class}; Object[] args = new Object[]{((ServletConfig)facade)}; SecurityUtil.doAsPrivilege("init",servlet,classType,args); } else { servlet.init(facade); } if ((loadOnStartup >= 0) && (jspFile != null)) { 鈥︹€︹€? if( System.getSecurityManager() != null) { Class[] classType = new Class[]{ServletRequest.class, ServletResponse.class}; Object[] args = new Object[]{req, res}; SecurityUtil.doAsPrivilege("service",servlet,classType,args); } else { servlet.service(req, res); } } instanceSupport.fireInstanceEvent(InstanceEvent.AFTER_INIT_EVENT,servlet); 鈥︹€︹€? return servlet; }
瀹冨熀鏈笂鎻忚堪浜嗗 Servlet 鐨勬搷浣滐紝褰撹杞戒簡 Servlet 鍚庡氨浼氳皟鐢?Servlet 鐨?init 鏂规硶锛屽悓鏃朵細浼犱竴涓?StandardWrapperFacade 瀵硅薄缁?Servlet锛岃繖涓璞″寘瑁呬簡 StandardWrapper锛孲ervletConfig 涓庡畠浠殑鍏崇郴鍥惧涓嬶細
鍥?13. ServletConfig 涓?StandardWrapperFacade銆丼tandardWrapper 鐨勫叧绯?/h5>
Servlet 鍙互鑾峰緱鐨勪俊鎭兘鍦?StandardWrapperFacade 灏佽锛岃繖浜涗俊鎭張鏄湪 StandardWrapper 瀵硅薄涓嬁鍒扮殑銆傛墍浠?Servlet 鍙互閫氳繃 ServletConfig 鎷垮埌鏈夐檺鐨勫鍣ㄧ殑淇℃伅銆?/p>
褰?Servlet 琚垵濮嬪寲瀹屾垚鍚庯紝灏辩瓑鐫€ StandardWrapperValve 鍘昏皟鐢ㄥ畠鐨?service 鏂规硶浜嗭紝璋冪敤 service 鏂规硶涔嬪墠瑕佽皟鐢?Servlet 鎵€鏈夌殑 filter銆?/p>
聽
Tomcat 涓叾瀹冪粍浠?/h2>
Tomcat 杩樻湁鍏跺畠閲嶈鐨勭粍浠讹紝濡傚畨鍏ㄧ粍浠?security銆乴ogger 鏃ュ織缁勪欢銆乻ession銆乵beans銆乶aming 绛夊叾瀹冪粍浠躲€傝繖浜涚粍浠跺叡鍚屼负 Connector 鍜?Container 鎻愪緵蹇呰鐨勬湇鍔°€?/p>
聽
聽