Tomcat源码系列:
- Tomcat初始化源码流程分析(图解及源码注释) (一)
- Tomcat初始化源码流程分析(图解及源码注释) (二)
- Tomcat启动源码流程分析(图解及源码注释) (三)
- Tomcat启动源码流程分析(图解及源码注释) (四)
- Tomcat请求源码流程分析(图解及源码注释) (五)
- Tomcat请求源码流程分析(图解及源码注释) (六)
本章为Tomcat初始化流程的第二章,主要内容有Server的初始化,Engine的初始化以及Connector的初始化
Tomcat初始化源码不适用于新手
文章内容只有部分流程的源码分析,通过代码注释的方法,仅适用于Tomcat的源码有一定的了解的同学
目录
1.Service初始化 --->StandardService.initInternal()
1.1 Engine初始化 ---> StandardEngine.initInternal()
1.1.1 StartStopExecutor初始化 ---> StandardEngine父类ContainerBase.initInternal()
1.2 Connector初始化 ---> Connector.initInternal()
1.2.2 ProtocolHandler初始化 ---> AbstractProtocol.init()
1.2.3 Enpoint.bind() ---> Enpoint.init()调用NioEndpoint.bind()
初始化流程图如下:
1.Service初始化 --->StandardService.initInternal()
protected void initInternal() throws LifecycleException {
//调用父类的initInternal
super.initInternal();
//engine是Tomcat的顶级容器
if (engine != null) {
engine.init();
}
//初始化线程池
for (Executor executor : findExecutors()) {
if (executor instanceof JmxEnabled) {
((JmxEnabled) executor).setDomain(getDomain());
}
//线程池会将子容器的初始化工作交给线程完成
executor.init();
}
// 初始化映射监听
mapperListener.init();
// 初始化连接器
synchronized (connectorsLock) {
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);
}
}
}
}
1.1 Engine初始化 ---> StandardEngine.initInternal()
protected void initInternal() throws LifecycleException {
// Ensure that a Realm is present before any attempt is made to start
// one. This will create the default NullRealm if necessary.
getRealm();//权限管理控制
super.initInternal(); //线程池的初始化
}
1.1.1 StartStopExecutor初始化 ---> StandardEngine父类ContainerBase.initInternal()
protected void initInternal() throws LifecycleException {
//engine实际的init方法
BlockingQueue<Runnable> startStopQueue = new LinkedBlockingQueue<>();
//将子容器开始或者停止的任务放入该线程池
startStopExecutor = new ThreadPoolExecutor(
getStartStopThreadsInternal(),
getStartStopThreadsInternal(), 10, TimeUnit.SECONDS,
startStopQueue,
new StartStopThreadFactory(getName() + "-startStop-"));
startStopExecutor.allowCoreThreadTimeOut(true);
super.initInternal();
}
1.2 Connector初始化 ---> Connector.initInternal()
1.2.1 CoyoteAdpater适配器初始化
protected void initInternal() throws LifecycleException {
super.initInternal();
// 初始化适配器
// 适配器作用:完成客服端请求到容器的映射 N个connector到一个container
// 用于Coyote的Request,Response和HttpServlet的Request和Response适配
adapter = new CoyoteAdapter(this);
//用于统领EndPoint以及Processor
//EndPoint负责Socket监听任务
//Processor负责处理请求
//设置适配器适配请求(由Coyote的Request以及Response转换为HttpServlet的Request以及Response)
protocolHandler.setAdapter(adapter);
// Make sure parseBodyMethodsSet has a default
if (null == parseBodyMethodsSet) {
setParseBodyMethods(getParseBodyMethods());
}
if (protocolHandler.isAprRequired() && !AprLifecycleListener.isInstanceCreated()) {
throw new LifecycleException(sm.getString("coyoteConnector.protocolHandlerNoAprListener",
getProtocolHandlerClassName()));
}
if (protocolHandler.isAprRequired() && !AprLifecycleListener.isAprAvailable()) {
throw new LifecycleException(sm.getString("coyoteConnector.protocolHandlerNoAprLibrary",
getProtocolHandlerClassName()));
}
if (AprLifecycleListener.isAprAvailable() && AprLifecycleListener.getUseOpenSSL() &&
protocolHandler instanceof AbstractHttp11JsseProtocol) {
AbstractHttp11JsseProtocol<?> jsseProtocolHandler =
(AbstractHttp11JsseProtocol<?>) protocolHandler;
if (jsseProtocolHandler.isSSLEnabled() &&
jsseProtocolHandler.getSslImplementationName() == null) {
// OpenSSL is compatible with the JSSE configuration, so use it if APR is available
jsseProtocolHandler.setSslImplementationName(OpenSSLImplementation.class.getName());
}
}
try {
//调度AbstractProtocol的init方法
//在此之间初始化Endpoint
protocolHandler.init();
} catch (Exception e) {
throw new LifecycleException(
sm.getString("coyoteConnector.protocolHandlerInitializationFailed"), e);
}
}
1.2.2 ProtocolHandler初始化 ---> AbstractProtocol.init()
public void init() throws Exception {
if (getLog().isInfoEnabled()) {
getLog().info(sm.getString("abstractProtocolHandler.init", getName()));
}
//完成jmx
if (oname == null) {
// Component not pre-registered so register it
oname = createObjectName();
if (oname != null) {
Registry.getRegistry(null, null).registerComponent(this, oname, null);
}
}
if (this.domain != null) {
rgOname = new ObjectName(domain + ":type=GlobalRequestProcessor,name=" + getName());
Registry.getRegistry(null, null).registerComponent(
getHandler().getGlobal(), rgOname, null);
}
String endpointName = getName();
endpoint.setName(endpointName.substring(1, endpointName.length()-1));
endpoint.setDomain(domain);
//初始化EndPoint
endpoint.init();
}
1.2.3 Enpoint.bind() ---> Enpoint.init()调用NioEndpoint.bind()
public void bind() throws Exception {
//实例化ServerSocketChannel,并绑定端口和地址
if (!getUseInheritedChannel()) {
serverSock = ServerSocketChannel.open();
socketProperties.setProperties(serverSock.socket());
InetSocketAddress addr = (getAddress()!=null?new InetSocketAddress(getAddress(),getPort()):new InetSocketAddress(getPort()));
//设置最大连接数量
serverSock.socket().bind(addr,getAcceptCount());
} else {
// Retrieve the channel provided by the OS
Channel ic = System.inheritedChannel();
if (ic instanceof ServerSocketChannel) {
serverSock = (ServerSocketChannel) ic;
}
if (serverSock == null) {
throw new IllegalArgumentException(sm.getString("endpoint.init.bind.inherited"));
}
}
serverSock.configureBlocking(true); //mimic APR behavior
// 初始化accepter以及poller的数量
if (acceptorThreadCount == 0) {
// FIXME: Doesn't seem to work that well with multiple accept threads
acceptorThreadCount = 1;
}
if (pollerThreadCount <= 0) {
//minimum one poller thread
pollerThreadCount = 1;
}
setStopLatch(new CountDownLatch(pollerThreadCount));
// 有必要初始化ssl
initialiseSsl();
// 开启selector
selectorPool.open();
}