Tomcat 绯荤粺鏋舵瀯涓庤璁℃ā寮忥紝绗?一 閮ㄥ垎: 宸ヤ綔鍘熺悊

Tomcat 绯荤粺鏋舵瀯涓庤璁℃ā寮忥紝绗?1 閮ㄥ垎: 宸ヤ綔鍘熺悊

鍘熸枃鍦板潃锛?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 绯荤粺鏋舵瀯涓庤璁℃ā寮忥紝绗?一 閮ㄥ垎: 宸ヤ綔鍘熺悊

浠庝笂鍥句腑鍙互鐪嬪嚭 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 鎺ュ彛

Tomcat 绯荤粺鏋舵瀯涓庤璁℃ā寮忥紝绗?一 閮ㄥ垎: 宸ヤ綔鍘熺悊

浠?Service 鎺ュ彛涓畾涔夌殑鏂规硶涓彲浠ョ湅鍑猴紝瀹冧富瑕佹槸涓轰簡鍏宠仈 Connector 鍜?Container锛屽悓鏃朵細鍒濆鍖栧畠涓嬮潰鐨勫叾瀹冪粍浠讹紝娉ㄦ剰鎺ュ彛涓畠骞舵病鏈夎瀹氫竴瀹氳鎺у埗瀹冧笅闈㈢殑缁勪欢鐨勭敓鍛藉懆鏈熴€傛墍鏈夌粍浠剁殑鐢熷懡鍛ㄦ湡鍦ㄤ竴涓?Lifecycle 鐨勬帴鍙d腑鎺у埗锛岃繖閲岀敤鍒颁簡涓€涓噸瑕佺殑璁捐妯″紡锛屽叧浜庤繖涓帴鍙e皢鍦ㄥ悗闈粙缁嶃€?/p>

Tomcat 涓?Service 鎺ュ彛鐨勬爣鍑嗗疄鐜扮被鏄?StandardService 瀹冧笉浠呭疄鐜颁簡 Service 鍊熷彛鍚屾椂杩樺疄鐜颁簡 Lifecycle 鎺ュ彛锛岃繖鏍峰畠灏卞彲浠ユ帶鍒跺畠涓嬮潰鐨勭粍浠剁殑鐢熷懡鍛ㄦ湡浜嗐€係tandardService 绫荤粨鏋勫浘濡備笅锛?/p>

鍥?3. StandardService 鐨勭被缁撴瀯鍥?/h5>

Tomcat 绯荤粺鏋舵瀯涓庤璁℃ā寮忥紝绗?一 閮ㄥ垎: 宸ヤ綔鍘熺悊

浠庝笂鍥句腑鍙互鐪嬪嚭闄や簡 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>

Tomcat 绯荤粺鏋舵瀯涓庤璁℃ā寮忥紝绗?一 閮ㄥ垎: 宸ヤ綔鍘熺悊

瀹冪殑鏍囧噯瀹炵幇绫?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 绫荤粨鏋勫浘

Tomcat 绯荤粺鏋舵瀯涓庤璁℃ā寮忥紝绗?一 閮ㄥ垎: 宸ヤ綔鍘熺悊

闄や簡鎺у埗鐢熷懡鍛ㄦ湡鐨?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 澶勭悊涓€娆¤姹傞『搴忓浘

Tomcat 绯荤粺鏋舵瀯涓庤璁℃ā寮忥紝绗?一 閮ㄥ垎: 宸ヤ綔鍘熺悊

锛?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>

Tomcat 绯荤粺鏋舵瀯涓庤璁℃ā寮忥紝绗?一 閮ㄥ垎: 宸ヤ綔鍘熺悊

锛?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. 鍥涗釜瀹瑰櫒鐨勫叧绯诲浘

Tomcat 绯荤粺鏋舵瀯涓庤璁℃ā寮忥紝绗?一 閮ㄥ垎: 宸ヤ綔鍘熺悊

锛?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 澶勭悊璇锋眰鐨勬椂搴忓浘

Tomcat 绯荤粺鏋舵瀯涓庤璁℃ā寮忥紝绗?一 閮ㄥ垎: 宸ヤ綔鍘熺悊

锛?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 鐨勫鐞嗚姹傛椂搴忓浘

Tomcat 绯荤粺鏋舵瀯涓庤璁℃ā寮忥紝绗?一 閮ㄥ垎: 宸ヤ綔鍘熺悊

锛?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 鎺ュ彛鐨勭被缁撴瀯

Tomcat 绯荤粺鏋舵瀯涓庤璁℃ā寮忥紝绗?一 閮ㄥ垎: 宸ヤ綔鍘熺悊

瀹冪殑鏍囧噯瀹炵幇绫绘槸 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>

Tomcat 绯荤粺鏋舵瀯涓庤璁℃ā寮忥紝绗?一 閮ㄥ垎: 宸ヤ綔鍘熺悊

锛?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>

Tomcat 绯荤粺鏋舵瀯涓庤璁℃ā寮忥紝绗?一 閮ㄥ垎: 宸ヤ綔鍘熺悊

Servlet 鍙互鑾峰緱鐨勪俊鎭兘鍦?StandardWrapperFacade 灏佽锛岃繖浜涗俊鎭張鏄湪 StandardWrapper 瀵硅薄涓嬁鍒扮殑銆傛墍浠?Servlet 鍙互閫氳繃 ServletConfig 鎷垮埌鏈夐檺鐨勫鍣ㄧ殑淇℃伅銆?/p>

褰?Servlet 琚垵濮嬪寲瀹屾垚鍚庯紝灏辩瓑鐫€ StandardWrapperValve 鍘昏皟鐢ㄥ畠鐨?service 鏂规硶浜嗭紝璋冪敤 service 鏂规硶涔嬪墠瑕佽皟鐢?Servlet 鎵€鏈夌殑 filter銆?/p>

Tomcat 涓叾瀹冪粍浠?/h2>

Tomcat 杩樻湁鍏跺畠閲嶈鐨勭粍浠讹紝濡傚畨鍏ㄧ粍浠?security銆乴ogger 鏃ュ織缁勪欢銆乻ession銆乵beans銆乶aming 绛夊叾瀹冪粍浠躲€傝繖浜涚粍浠跺叡鍚屼负 Connector 鍜?Container 鎻愪緵蹇呰鐨勬湇鍔°€?/p>