赞
踩
上节看了容器的初始化和启动,知道了Tomcat初始化和启动都是由Server.init(),Server.start(),层层向下依次触发各个组件的initInternal(),startInternal()方法进行初始化和启动,从本片开始,就从各组件的初始化和启动开始读源码(本文Tomcat8.5)
本文的Service实现类是StandardService,内部从配置文件中看到,内部是多个Connector和一个Engine组成,来看代码
就是调用各子组件(Engine\Connector\Mapper\Executor)的初始化和启动方法
- public class StandardService extends LifecycleMBeanBase implements Service {
- // 父组件Server的引用
- private Server server = null;
-
- // 多个Connector,每种连接一个Connector http,https,向相同协议不同端口的连接等
- protected Connector connectors[] = new Connector[0];
-
- // 用来synchronized
- private final Object connectorsLock = new Object();
-
- // Service下 和Connector和Engine同级别的组件Executor,StandardThreadExecutor
- // ThreadPoolExecutor的封装
- protected final ArrayList<Executor> executors = new ArrayList<>();
-
- // 子组件Engine
- private Engine engine = null;
-
- protected final Mapper mapper = new Mapper();
-
- protected final MapperListener mapperListener = new MapperListener(this);
-
- @Override
- protected void initInternal() throws LifecycleException {
- // 注册当前对象MBean
- super.initInternal();
-
- // 初始化engine
- if (engine != null) {
- engine.init();
- }
-
- // 初始化Executor
- for (Executor executor : findExecutors()) {
- if (executor instanceof JmxEnabled) {
- ((JmxEnabled) executor).setDomain(getDomain());
- }
- executor.init();
- }
-
- // 初始化mapperListener,只是注册JMX
- mapperListener.init();
-
- // 初始化Connector
- 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);
- }
- }
- }
- }
-
- protected void startInternal() throws LifecycleException {
-
- // 设置Starting状态
- setState(LifecycleState.STARTING);
-
- // 启动Engine
- if (engine != null) {
- synchronized (engine) {
- engine.start();
- }
- }
-
- // 启动executor
- synchronized (executors) {
- for (Executor executor: executors) {
- executor.start();
- }
- }
-
- //mapperListener启动
- mapperListener.start();
-
- // Connector启动
- synchronized (connectorsLock) {
- for (Connector connector: connectors) {
- try {
- // If it has already failed, don't try and start it
- if (connector.getState() != LifecycleState.FAILED) {
- connector.start();
- }
- } catch (Exception e) {
- log.error(sm.getString(
- "standardService.connector.startFailed",
- connector), e);
- }
- }
- }
- }
- }
Connector和Engine下节看
对请求进行路由, Mapper中有MappedHost数组,Mapper内部类有MappedHost\MappedContext\MappedWrapper 几种,和Container容器有四个子接口Engine,Host,Context,Wrapper一一对应
目的是请求来时快速查找匹配的具体的wrapper(Servlet)
- public final class Mapper {
- volatile MappedHost[] hosts = new MappedHost[0];
- }
在tomcat服务器中,有多个service,每个service有一个engine,而一个engine可以部署多个host,一个host又可以部署多个context,一个context多个wrapper,Mapper类中也符合这个层次。
查询当前Engine所部署的相关应用更新到mapper中,并监听Engine下容器动态更新mapper
- public class MapperListener extends LifecycleMBeanBase
- implements ContainerListener, LifecycleListener {
- private final Mapper mapper;
-
- private final Service service;
-
- public MapperListener(Service service) {
- this.service = service;
- this.mapper = service.getMapper();
- }
- }
首先MapperListener继承 LifecycleMBeanBase,说明对象的启动会被注册到jmx上面去,其次实现了两个Listener,LifecycleListener之前见过,监听顶层的生命周期变更事件触发lifecycleEvent()方法,ContainerListener监听容器Container的变更事件触发containerEvent()方法
- public interface ContainerListener {
- public void containerEvent(ContainerEvent event);
- }
org.apache.catalina.mapper.MapperListener#startInternal
- @Override
- public void startInternal() throws LifecycleException {
- // 设置启动状态
- setState(LifecycleState.STARTING);
-
- Engine engine = service.getContainer();
- if (engine == null) {
- return;
- }
-
- // <Engine name="Catalina" defaultHost="localhost">
- // 获取defaultHost属性, 并检查是否存在对应的<Host >标签
- findDefaultHost();
-
- // 将Engine及其子容器都注册这个MapperListener对象
- addListeners(engine);
-
- // 获取engine的所有Host配置,注册到Mapper中
- // 注册host又会把其下所有context注册,接着往下注册所有wrapper
- Container[] conHosts = engine.findChildren();
- for (Container conHost : conHosts) {
- Host host = (Host) conHost;
- if (!LifecycleState.NEW.equals(host.getState())) {
- // Registering the host will register the context and wrappers
- registerHost(host);
- }
- }
- }
- private void registerHost(Host host) {
-
- String[] aliases = host.findAliases();
-
- // mapper中增加host
- mapper.addHost(host.getName(), aliases, host);
-
- // 注册context到mapper
- for (Container container : host.findChildren()) {
- if (container.getState().isAvailable()) {
- registerContext((Context) container);
- }
- }
- }
org.apache.catalina.mapper.MapperListener#containerEvent
监听器回调方法,根据事件注册或移除监听器,更新mapper
org.apache.catalina.mapper.MapperListener#lifecycleEvent
也是根据事件更新mapper
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。