在上文中,看到在connector类中,是启动、初始化、停止、恢复protocolHandler对象,而该对象的类型是ProtocolHandler,它属于org.apache.coyote 包。
该接口签名如下public interface ProtocolHandler,是协议的抽象,包括线程的。Processor是单线程的基于流的协议,不适用于类似于JNI的JK协议。它是coyote连接器实现的主要接口,Adaper是coyote Servlet容器实现的主要接口。~~~文档太烂了!!!
原文:
Abstract the protocol implementation, including threading, etc. Processor is single threaded and specific to stream-based protocols, will not fit Jk protocols like JNI. This is the main interface to be implemented by a coyoute connector. Adapter is the main interface to be impleneted by a coyote servlet container
实现了改接口的类有:
AjpAprProtocol, AjpProtocol, Http11AprProtocol, Http11NioProtocol, Http11Protocol, JkCoyoteHandler, MemoryProtocolHandler
主要是各种协议的处理。首先看Http11Protocol,该类属于org.apache.coyote.http11 包。
该类的签名如下
public class Http11Protocol implements ProtocolHandler, MBeanRegistration
init方法:
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);//SSLImplementation是抽象类,会返回JSSEImplementation实例
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;
}
if (socketFactory!=null) {//设置socketFactory工厂的属性
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();//初始化endpoint
} catch (Exception ex) {
log.error(sm.getString("http11protocol.endpoint.initerror"), ex);
throw ex;
}
if (log.isInfoEnabled())
log.info(sm.getString("http11protocol.init", getName()));
}
endpoint对象是JIoEndpoint的实例,该类 实现一个简单的服务器模型:一个线程监听套接字并为每个传入的连接创建一个新的工作线程。
cHandler是Http11ConnectionHandler类的对象,该类是Http11Protocol的内部类。
sslImplementation.getServerSocketFactory();
会调用
public ServerSocketFactory getServerSocketFactory() {
ServerSocketFactory ssf = factory.getSocketFactory();
return ssf;
}
而factory是JSSEFactory的对象。返回一个JSSESocketFactory类型的工厂,由该类负责创建socket的工作,关于该类下面再进行介绍。
否则根据socketFactoryName加载ServerSocketFactory类型的工厂。
初始化endpoint的时候回调用:
public void init()
throws Exception {
if (initialized)
return;
// Initialize thread count defaults for acceptor
if (acceptorThreadCount == 0) {
acceptorThreadCount = 1;
}
if (serverSocketFactory == null) {
serverSocketFactory = ServerSocketFactory.getDefault();
}
if (serverSocket == null) {
try {
if (address == null) {
serverSocket = serverSocketFactory.createSocket(port, backlog);
} else {
serverSocket = serverSocketFactory.createSocket(port, backlog, address);
}
} catch (BindException be) {
if (address == null)
throw new BindException(be.getMessage() + "<null>:" + port);
else
throw new BindException(be.getMessage() + " " +
address.toString() + ":" + port);
}
}
//if( serverTimeout >= 0 )
// serverSocket.setSoTimeout( serverTimeout );
initialized = true;
}
该方法主要负责初始化一个serversocket。
此后的start、rusume、stop方法都是针对endpoint来执行的。
另外在Http11Protocol类中还有一个静态内部类:
protected static class Http11ConnectionHandler implements Handler
该类的主要方法是process用来处理接受到得socket,处理socket的是Http11Processor类的对象,在Http11ConnectionHandler 中维持了一个ConcurrentLinkedQueue来持有Http11Processor对象。每次处理的时候,从队列中取出一个Http11Processor对象来处理请求,如果队列为空,则使用createProcessor方法创建,处理完成后将Http11Processor对象添加到队列中。
在下一小节中,主要对JIoEndpoint以及Http11Processor进行介绍。