这篇文章主要为大家展示了“Tomcat配置文件的示例分析”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“Tomcat配置文件的示例分析”这篇文章吧。
网站的建设创新互联建站专注网站定制,经验丰富,不做模板,主营网站定制开发.小程序定制开发,H5页面制作!给你焕然一新的设计体验!已为成都混凝土搅拌机等企业提供专业服务。
Tomcat用户一定都知道其包含一个名为server.xml的配置文件。毕竟都在这里改过端口或者以目录形式部署过应用。
那这个配置文件里的配置信息又是如何对应到Tomcat中的具体对象的。开发的朋友马上会在大脑里浮现出Dom4j、Jdom、JAXB、SAX...一系列的XML解析工具。
不过,这里Tomcat用的并不是上面提到的这几位,而是Apache社区自己的XML解析工具Digester.
在Digester的Wiki里,这样介绍自己:
Many projects read XML configuration files to provide initialization of various Java objects within the system. There are several ways of doing this, and the Digester component was designed to provide a common implementation that can be used in many different projects.
我们来看Tomcat内部对于Digester是如何使用的。
在Catalina类内,我们会发现许多类似这样的代码:
digester.addObjectCreate("Server/Service",
"org.apache.catalina.core.StandardService",
"className");
digester.addSetProperties("Server/Service");
digester.addSetNext("Server/Service",
"addService",
"org.apache.catalina.Service");digester.addRuleSet(new NamingRuleSet("Server/GlobalNamingResources/"));
digester.addRuleSet(new EngineRuleSet("Server/Service/"));
digester.addRule("Server/Service/Connector",
new ConnectorCreateRule());
以上这些是配置,最终的解析是通过parse这样一个方法
inputSource.setByteStream(inputStream);
digester.push(this);
digester.parse(inputSource);
那是不是整个parse就是解析配置文件是否非法呢? Of course Not.
对应上面标红的addObjectCreate, addSetProperties,这些操作的背后,其实是添加了一系列的Rule。
这是个抽象类,对于上面添加的不同的Rule,有不同的实现。
其中,create对应的实现是ObjectCreateRule
public void addObjectCreate(String pattern, String className,
String attributeName) {
addRule(pattern,
new ObjectCreateRule(className, attributeName));
}
setProperties对应的是SetPropertiesRule。
public void addSetProperties(String pattern) {
addRule(pattern,
new SetPropertiesRule());
}
setNext对应的Rule是SetNextRule
在解析过程中,SetNextRule实质上,是会通过反射,调用对应方法。下图是在执行Catalina的一个setServer的Rule
对应setProperties的执行,也是通过反射,设置对应属性的值。例如,下图是在设置Server的port属性值。
这时,你可能会问,那这些对象设置属性,创建新对象等,他们之间又是如何关联起来的呢?
看这里,在Digester内部维护了一个stack结构,从下到上,越向上的层级越高。如下图,从Catalina,向上到Server,再到Service
进行Set的时候,会从顶向下,两个相邻的,即为父子关系,从而进行parent的child设置。
public void end(String namespace, String name) throws Exception {
// Identify the objects to be used
Object child = digester.peek(0);
Object parent = digester.peek(1);
// Call the specified method
IntrospectionUtils.callMethod1(parent, methodName,
child, paramType, digester.getClassLoader());
}
而对应的属性设置的时候,则是从stack里取最上面的一个,反射进行属性设置。
整个stack的最底层,则是Catalina,在获取配置文件输入流之后进行的push操作
public void push(Object object) {
if (stack.size() == 0) {
root = object;
}
stack.push(object);
}
Digester整体的设计思路,在XML元素开始,创建Object的rule执行时,把新创建的对象push到stack中。对象会保留在stack中,直到XML元素的结尾出现。
Rule的解析过程主要涉及到上面Rule类的几个方法
begin 元素开始时会执行
body 嵌套的元素匹配时执行
end 元素结束执行
finish 整个parse结束时调用
在parse结束之后,整个xml内容对应的Java对象已经创建成功,开动吧!
在Tomcat内部,Digester用在解析server.xml配置文件,MBean的描述文件,TLD文件校验等等。
具体用法也比较简单,new 一个Digester对象,然后设置具体的对象Rule,类似于各类的match规则,之后parse即可。
比如下面这个xml文件
解析的Digester代码只有这些
Digester digester = new Digester();
digester.setValidating( false );
digester.addObjectCreate( "foo", "mypackage.Foo" );
digester.addSetProperties( "foo" );
digester.addObjectCreate( "foo/bar", "mypackage.Bar" );
digester.addSetProperties( "foo/bar" );
digester.addSetNext( "foo/bar", "addBar", "mypackage.Bar" );
InputStream is = digester.getClass().getClassLoader().getResourceAsStream("mytest.xml");
Foo foo = digester.parse(is);
当然,具体XML文件需要对应的Java类还是需要的。
以上是“Tomcat配置文件的示例分析”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注创新互联行业资讯频道!