2013-11-16java
在tomcat中须要解决响应客户端请求的Socket问题,即接收客户端的请求,Connector做为tomcat中的连接器,管理负责监控网络端口的网络链接器。它是以管理者的身份存在,不涉及具体的网络接口监听,只负责管理监听网络组件,负责组件的所需资源的调配和组件的运行状态控制。做为一个壳,它能管理实现ProtocolHandler接口的网络监听组件,能方便替换网络监听组件。apache
Connector做为一个tomcat组件的生命周期中应该经历这样一个过程:初始化-启动-中止-销毁.做为Connector,它须要解决一些问题tomcat
监听网络端口组件
在带一个参数的构造器中指定监听网络端口组件,传递协议版本或者类名,setProtocol(String)方法负责辨别和之人协议监听网络端口的组件,在构造器中实例化监控网络端口组件。网络
/** * 指定协议类型 * @param protocol * @throws Exception */ public Connector(String protocol) throws Exception { 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)); } }
Connector默认的网络端口监听组件是org.apache.coyote.http11.Http11Protocol,同时还附加指定一些常量配置。在完成指定组件后,Connector须要完成组件的初始化任务。app
init()
负责完成Connector组件的初始化任务,首先先判断Connector所依附的Service是不为空,而后判断所寄居的容器不为空,若为空,findContainer()方法经过JMX的方式来查询所寄居的容器,同时在方法内调用真正初始化方法initialize()。dom
initialize()
真正负责完成组件的初始化任务。在方法内部主要完成下面几步:this
/** * Initialize this connector (create ServerSocket here!) * 初始化链接器,建立ServerSocket */ public void initialize() throws LifecycleException { if (initialized) { if (log.isInfoEnabled()) log.info(sm.getString("coyoteConnector.alreadyInitialized")); return; } this.initialized = true; if (oname == null && (container instanceof StandardEngine)) { try { // we are loaded directly, via API - and no name was given to us StandardEngine cb = (StandardEngine) container; oname = createObjectName(cb.getName(), "Connector"); Registry.getRegistry(null, null).registerComponent(this, oname, null); controller = oname; } catch (Exception e) { log.error("Error registering connector ", e); } if (log.isDebugEnabled()) log.debug("Creating name for connector " + oname); } // Initializa adapter //初始化适配器 adapter = new CoyoteAdapter(this); //设置协议处理的适配器 protocolHandler.setAdapter(adapter); // Make sure parseBodyMethodsSet has a default if (null == parseBodyMethodsSet) setParseBodyMethods(getParseBodyMethods()); IntrospectionUtils.setProperty(protocolHandler, "jkHome", System.getProperty("catalina.base")); try { protocolHandler.init();//协议处理器初始化 } catch (Exception e) { throw new LifecycleException(sm.getString( "coyoteConnector.protocolHandlerInitializationFailed", e)); } }
从上面能够看出,初始化是在作资源配置工做.在组件初始化化完成后,就是组件启动的任务了,start()方法负责这个功能。debug
start() 负责组件的启动任务,在方法内部作些事件通知和启动网络监听端口组件.code
/** * Begin processing requests via this Connector. * 开始监听请求 * * @exception LifecycleException * if a fatal startup error occurs */ public void start() throws LifecycleException { if (!initialized) initialize(); // Validate and update our current state if (started) { if (log.isInfoEnabled()) log.info(sm.getString("coyoteConnector.alreadyStarted")); return; } lifecycle.fireLifecycleEvent(START_EVENT, null); started = true; // We can't register earlier - the JMX registration of this happens // in Server.start callback if (this.oname != null) { // We are registred - register the adapter as well. try { Registry.getRegistry(null, null).registerComponent( protocolHandler, createObjectName(this.domain, "ProtocolHandler"), null); } catch (Exception ex) { log.error( sm.getString("coyoteConnector.protocolRegistrationFailed"), ex); } } else { if (log.isInfoEnabled()) log.info(sm.getString("coyoteConnector.cannotRegisterProtocol")); } try { protocolHandler.start();//协议监听 } catch (Exception e) { String errPrefix = ""; if (this.service != null) { errPrefix += "service.getName(): \"" + this.service.getName() + "\"; "; } throw new LifecycleException(errPrefix + " " + sm.getString( "coyoteConnector.protocolHandlerStartFailed", e)); } if (this.domain != null) { mapperListener.setDomain(domain); // mapperListener.setEngine( service.getContainer().getName() ); mapperListener.init(); try { ObjectName mapperOname = createObjectName(this.domain, "Mapper"); if (log.isDebugEnabled()) log.debug(sm.getString( "coyoteConnector.MapperRegistration", mapperOname)); Registry.getRegistry(null, null).registerComponent(mapper, mapperOname, "Mapper"); } catch (Exception ex) { log.error( sm.getString("coyoteConnector.protocolRegistrationFailed"), ex); } } }
启动完成后组件监听网络端口,对网络监听端口组件有暂定监听的需求和回复监听需求,经过pause()
和resume()
完成,方法内部负责调用组件的暂停监听和恢复监听方法.组件的中止运行由stop()
完成.orm
stop()
负责组件的中止功能,也即中止网络监听端口组件。
public void stop() throws LifecycleException { // Validate and update our current state if (!started) { log.error(sm.getString("coyoteConnector.notStarted")); return; } lifecycle.fireLifecycleEvent(STOP_EVENT, null); started = false; try { mapperListener.destroy(); Registry.getRegistry(null, null).unregisterComponent( createObjectName(this.domain, "Mapper")); Registry.getRegistry(null, null).unregisterComponent( createObjectName(this.domain, "ProtocolHandler")); } catch (MalformedObjectNameException e) { log.error(sm .getString("coyoteConnector.protocolUnregistrationFailed"), e); } try { protocolHandler.destroy(); } catch (Exception e) { throw new LifecycleException(sm.getString( "coyoteConnector.protocolHandlerDestroyFailed", e)); } }
以上几步即完成了组件的stop任务,组件的销毁工做交由destory()完成,所作的工做就是撤销JMX注册和Service移除Connector组件
Connector做为tomcat的链接器组件,负责网络端口监听组件的管理配置,能管理实现ProtocolHandler接口,在不须要修改代码的状况下,方便实现网络端口监听组件的替换,对组件管理和代码维护颇有帮助.
hold on