ProtocolHandler和Http11Protocol分析-tomcat6.x源碼閱讀

2013-11-17java

tomcat處理HTTP請求,須要有一個網絡端口監聽ServerSocket來完成任務。接口ProtocolHandler被設計成控制網絡端口監聽組件運行,負責組件的生命週期控制,這個接口不是規範網絡端口監聽組件的功能,而是負責維護組件的生命週期。從名字上面看,屬於網絡協議處理者,但它不負責這功能,而是將其交給org.apache.coyote.Adapter來完成,這麼設計估計是爲了方便維護和拓展新功能。Http11Protocol是ProtocolHandler接口的一個實現(是Connector中默認處理協議),被設計成用來處理HTTP1.1網絡協議的請求,經過該類能夠完成在某個網絡端口上面的監聽,同時以HTTP1.1的協議來解析請求內容,而後將請求傳遞到Connector所寄居的Container容器pipeline流水工做線上處理。apache

Http11Protocol
實現ProtocolHandler接口,爲HTTP1.1而設計的協議處理組件,負責管理Http11ConnectionHandler和JIoEndpoint,前者負責處理HTTP1.1的鏈接,包括維護請求鏈接隊列,爲鏈接分配線程,設置鏈接屬性等信息;後者是真正負責監控網絡端口的組件,啓動一個ServerSocket,不間斷監聽來自客戶端的請求。Http11Protocol還包含了與HTTP1.1相關的許多屬性信息,3個很重要的屬性是包含前面提供的兩個,還有一個ServerSocketFactory,用於定製ServerSocket。tomcat

瞭解一下Http11Protocol的初始化,啓動,中止,註銷功能.看看在這些重要的步驟中如何處理Http11ConnectionHandler和JIoEndpoint網絡

init()
負責組件的初始化,在方法內部完成了對JIoEndpoint的資源配置.dom

  • 爲JIoEndpoint設置鏈接管理器(Http11ConnectionHandler)
  • 判斷ServerSocketFactory不爲null,爲JIoEndpoint設置ServerSocketFactory
  • 判斷ServerSocketFactory不爲null,爲ServerSocketFactory設置屬性值
  • JIoEndpoint初始化
public void init() throws Exception {
		endpoint.setName(getName());
		endpoint.setHandler(cHandler);//設置鏈接管理器

		// Verify the validity of the configured socket factory
		try {
			if (isSSLEnabled()) {
				sslImplementation = SSLImplementation
						.getInstance(sslImplementationName);
				socketFactory = sslImplementation.getServerSocketFactory();
				endpoint.setServerSocketFactory(socketFactory);
			} else if (socketFactoryName != null) {
				socketFactory = (ServerSocketFactory) Class.forName(
						socketFactoryName).newInstance();
				endpoint.setServerSocketFactory(socketFactory);
			}
		} catch (Exception ex) {
			log.error(sm.getString("http11protocol.socketfactory.initerror"),
					ex);
			throw ex;
		}
		//設置socketFactory屬性
		if (socketFactory != null) {
			Iterator<String> attE = attributes.keySet().iterator();
			while (attE.hasNext()) {
				String key = attE.next();
				Object v = attributes.get(key);
				socketFactory.setAttribute(key, v);
			}
		}

		try {
			endpoint.init();//初始化
		} catch (Exception ex) {
			log.error(sm.getString("http11protocol.endpoint.initerror"), ex);
			throw ex;
		}
		if (log.isInfoEnabled())
			log.info(sm.getString("http11protocol.init", getName()));
	}

init()方法中,爲JIoEndpoint設置鏈接處理器,用於處理來自客戶端的鏈接,判斷並處理ServerSocketFactory,最後一步初始化JIoEndpoint.socket

start()
負責組件的啓動任務.完成JMX的註冊和啓動JIoEndpoint組件.this

public void start() throws Exception {
		if (this.domain != null) {
			try {
				tpOname = new ObjectName(domain + ":" + "type=ThreadPool,name="
						+ getName());
				Registry.getRegistry(null, null).registerComponent(endpoint,
						tpOname, null);
			} catch (Exception e) {
				log.error("Can't register endpoint");
			}
			rgOname = new ObjectName(domain
					+ ":type=GlobalRequestProcessor,name=" + getName());
			Registry.getRegistry(null, null).registerComponent(cHandler.global,
					rgOname, null);
		}

		try {
			endpoint.start();
		} catch (Exception ex) {
			log.error(sm.getString("http11protocol.endpoint.starterror"), ex);
			throw ex;
		}
		if (log.isInfoEnabled())
			log.info(sm.getString("http11protocol.start", getName()));
	}

pause()resume()destroy()
這3個方法都比較簡單,分別控制JIoEndpoint暫定監聽網絡和恢復監聽以及註銷組件.線程

Http11Protocol組件的定位是管理JIoEndpoint,JIoEndpoint自己與具體協議無關,只負責監聽網絡端口並建立鏈接,如何解析請求內容則交由鏈接處理器來完成,例如Http11ConnectionHandler鏈接處理器,專門處理HTTP1.1協議鏈接。Http11Protocol管理JIoEndpoint,爲JIoEndpoint提供鏈接處理器.設計

堅持code

相關文章
相關標籤/搜索