下载
启动:
通过 启动类 Bootstrap中的main方法启动
启动过程:之解析xml的过程
main方法中调用 load方法,load方法中通过反射,调用Catalina 类中的load方法
Catalina 中的load 方法 的解析
- 创建 Digester(消化器),里面包含解析xml的rules(规则)
- 通过digester 解析xml, 可以以项目根目录下 conf文件夹下的server.xml 为例
启动过程:之初始化
- createStartDigester() 方法详解
关键是构建Digester 对象 digester,
digester 对象中有个属性rules[RulesBase], rulesBase中有一个属性 cache[Map<String,List>]
创建rule,就是在为cache put值。此处put的值,需要注意,后面会用来解析xml
- 解析xml详解
第二个 digester 中比较重要的属性是 stack[ArrayStack]
解析xml第一件事,就是把this,即Catalina的对象 pust到 stack中(此处的作用是为catalina对象,添加server属性的值。后续会讲)
然后开始 解析 conf文件夹下的 server.xml 文件。 采用的是 SAXParse 的方法,解析xml。即一行一行的解析(不要理解为一行一行的读取) ⇒ SAXParse 详解
- startElement 方法 的解析
图一:
图二:
图一:createStartDigester 方法构建的rules
图二:match 是对 server.xml 元素 的拼接
第一个startElement,match = Server,匹配图一的 rules为
[ObjectCreateRule[className=org.apache.catalina.core.StandardServer, attributeName=className],
SetPropertiesRule[],
SetNextRule[methodName=setServer, paramType=org.apache.catalina.Server]
]
然后挨个调用Rule的start方法,
ObjectCreateRule 的start方法 创建 StandardServer对象,并pust到digester的stack中
SetPropertiesRule的start方法 取(只是获取,并未出栈)之前push的对象,通过反射,为其赋值属性
SetNextRule 的start方法 通常是没做什么事情
-
endElement 方法解析
*理解有难度的话,最好先熟悉 SAXParse,之后再对照着server.xml 文件阅读代码*
之前是通过xml 元素拼接获取的rule,tomcat巧妙的利用了xml,开始标签和结束标签 成对 出现的规则,startElement的时候,顺序入栈,endElement的时候,顺序出栈,可以保证Digest 对象中
stack元素存储的 对象,与matches中存储的规则,相对应。
开始对之前创建的对象,执行 end(个rule的执行顺序,与start的顺序刚好相反)
ObjectCreateRule[className=null, attributeName=className],
SetPropertiesRule[],
SetNextRule[methodName=addLifecycleListener, paramType=org.apache.catalina.LifecycleListener]
SetNextRule 执行end() 方法
之前Catalina 对象中的 stack 属性中 push的对象,是散的,各个对象没有任何关系,相对独立。
需要引用起来。根据 server.xml 可知,Listener元素的endElement处,会将 当前创建的 listener对象,添加到之前创建的Server中。
以此类推 整个server.xml 的解析中的 setNextRule中的end方法
便是 为StandardServer对象添加 多个listener 对象。
为StandardServer 添加 StandardService
为StandardService 添加 Connector 对象
…
最后将 StandardServer 添加到Catalina对象中,这就是 Catalina中的Server中 有值的原因
SetPropertiesRule 执行end() 方法
大部分都没做什么
ObjectCreateRule 执行end() 方法
当前处理的对象,出栈
后续转 Tomcat源码二