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的作用.