浅析Tomcat之Connector

Tomcat7默认连接器是类org.apache.catalina.connector.Connector.连接器的作用是等待引入的HTTP请求,创建request对象和response对象,然后调用org.apache.catalina.Container接口的invoke方法将request和response传递给servlet容器.在invoke方法内部,servlet容器会载入相应的servlet类,调用其service方法,管理session对象,记录错误消息等操作.

Connector类继承了LifecycleMBeanBase.其设计思想跟StandardServer等类似.控制其内置组件的生命周期,在生命周期内对外提供服务.它是受StandardService生命周期控制的.我们可以看下service的初始化方法.

 protected void initInternal() throws LifecycleException {

	super.initInternal();

	if (container != null) {
		container.init();
	}

	// Initialize any Executors
	for (Executor executor : findExecutors()) {
		if (executor instanceof LifecycleMBeanBase) {
			((LifecycleMBeanBase) executor).setDomain(getDomain());
		}
		executor.init();
	}

	// Initialize our defined Connectors
	synchronized (connectors) {
		for (Connector connector : connectors) {
			try {
				connector.init();
			} catch (Exception e) {
				String message = sm.getString(
						"standardService.connector.initFailed", connector);
				log.error(message, e);

				if (Boolean.getBoolean("org.apache.catalina.startup.EXIT_ON_INIT_FAILURE"))
					throw new LifecycleException(message);
			}
		}
	}
}

   我们可以看到StandardService初始化是调用了容器的初始化,Excuctor的初始化和Connector的初始化.而Connector的责任是根据自身的协议操作来接收不同类型的网络连接.它有2个比较重要的属性,protocolHandlerClassName和protocolHandler.前者是字符串类型,来说明后者的具体实现类.ProtocolHandler是一个接口.它定义了了具体网络协议连接的操作.protocolHandlerClassName有一个默认值.而protocolHandler是在Connector构造函数中初始化的.其中调用了一个比较重要的方法setProtocol,它是用来设置protocolHandlerClassName的.

public Connector(String protocol) {
	setProtocol(protocol);
	// Instantiate protocol handler
	try {
		Class<!--?--> clazz = Class.forName(protocolHandlerClassName);
		this.protocolHandler = (ProtocolHandler) clazz.newInstance();
	} catch (Exception e) {
		log.error(sm.getString(
				"coyoteConnector.protocolHandlerInstantiationFailed"), e);
	}
}
public void setProtocol(String protocol) {

	if (AprLifecycleListener.isAprAvailable()) {
		if ("HTTP/1.1".equals(protocol)) {
			setProtocolHandlerClassName
				("org.apache.coyote.http11.Http11AprProtocol");
		} else if ("AJP/1.3".equals(protocol)) {
			setProtocolHandlerClassName
				("org.apache.coyote.ajp.AjpAprProtocol");
		} else if (protocol != null) {
			setProtocolHandlerClassName(protocol);
		} else {
			setProtocolHandlerClassName
				("org.apache.coyote.http11.Http11AprProtocol");
		}
	} else {
		if ("HTTP/1.1".equals(protocol)) {
			setProtocolHandlerClassName
				("org.apache.coyote.http11.Http11Protocol");
		} else if ("AJP/1.3".equals(protocol)) {
			setProtocolHandlerClassName
				("org.apache.coyote.ajp.AjpProtocol");
		} else if (protocol != null) {
			setProtocolHandlerClassName(protocol);
		}
	}

}

   从上面的代码设计中,不难猜出Connector根据不同的protocol来实例化不同的ProtocolHandler其对不同网络类型的连接就托管到ProtocolHandler中了.事实上就是如此,不同协议的连接管理分散到不同ProtocolHandler的生命周期中去.Connector起到了facade的作用.

 

 

首发于泛泛之辈http://www.lihongkun.com/archives/97

猜你喜欢

转载自lihkstyle.iteye.com/blog/1944395