网上看了很多tomcat的分析资料,分析的很好也很全面.这里我自己写篇作个笔记.
1.接口调用的流程大体如下
1.首先Bootstrap.java这个final类是程序的入口类.
在main函数里面,根据我们传递的参数来确定执行的动作,如果没有任何参数,那么就执行start操作.这里从start操作来看其执行的流程
2.先执行init操作,这个操作的主要目地就是通过反射机制来生成一个Catalina类的对象
3.对象生成之后就是load操作,这里也是通过反射机会调用Catalina类的load接口.这个接口主要是做加载的预处理以及对server.xml配置的读取,主要过程如下:
1)通过setSource来设定,要加载的server.xml的位置
2)createStartDigester这个函数,逻列了tomcat所有支持的类名和方法名.所有的server.xml配置前辍必须是这时所罗列的一种,不然不支持.
3)将Catalina对象全身压栈
4)对server.xml文件进行解析.这里要清楚的是digester类是DefaultHandler2的子类,在对xml进行parse的时候,会自动调用startElement和endElement接口.
这里是将server.xml配置参数与createStartDigester函数所注册的数据进行一一对比.如果match了,则会在startElement函数里面调用begin,通过反射生成对象.为后面的方面调用提供参数来源.
在endElement调用时,会调用SetNextRule类的end函数来进行方法的反射调用.此时也会调用其它match的对象end函数.如果有自己实现end的接口,一般会把栈底的数据pop掉,而不是栈顶.这样做的原因是,最近刚入栈的对象,会被用来作方法反射调用的第一个参数.
这里需要注意的是,根据代码的逻辑.有且只会有一个server它是StandardServer对象.所有的service注册都是在Server里面注册的.所有的控件的层次关系如下图:根据代码所示层次关系很清楚了.
Server下面只有Listener和Service,这两者的个数不受限
service下面有Listener,Excutor,Connector和第二上面的第二幅图的Container
根据server.xml service和各种控件增加完成之后,就是Server的init和start调用了,这两个调用会涉及到其下面各个子模块的相关函数的调用
下面就是init start的调用流程了对standardservice来说.每个service只有一个Engine和MapperListener,有多个Executor和Connector.
对Connector来说,根据其传入的通信协议来确定加载的类.代码截图:Connector 如上图,根据传入的不同的通信协议.生成不同的处理对象.而不同的处理对象,一般来说有自己特定的通信port.基本都是使用的tcp,那么创建一个线程监听指定的port,然后验证数据合法性等操作合,交给container处理了.
StandardThreadExecutor 这里主要是提供线程池,上面的connector线程是从这里的线程池获取的.
StandardEngine 是Container的容器子类.负责处理connect 请求.主要是通过addChild方法来添加Host类成员.而addChild基本是在catalina里面通过反射调用的.
StandardContext 是容器的核心处理地方了,startInternal方法体比较长,没仔细分析。主要还是wrapper进行处理
context代码比较复杂,还没完全理解。暂时先到这里吧