总结

王朝学院·作者佚名  2016-08-27
窄屏简体版  字體: 小  |  中  |  大  |  超大  

前言作为java程序员,对于tomcat的server.xml想必都不陌生。本文基于Tomcat7.0的Java源码,对server.xml文件是如何加载的进行分析。

源码分析Bootstrap的load方法是加载tomcat的server.xml的入口,load方法实际通过反射调用了Catalina的load方法,见代码清单1。

代码清单1

/*** Load daemon.*/PRivatevoidload(String[] arguments)throwsException {//Call the load() methodString methodName = "load";

Object param[];

Class<?>paramTypes[];if(arguments==null|| arguments.length==0) {

paramTypes=null;

param=null;

}else{

paramTypes=newClass[1];

paramTypes[0] =arguments.getClass();

param=newObject[1];

param[0] =arguments;

}

Method method=catalinaDaemon.getClass().getMethod(methodName, paramTypes);if(log.isDebugEnabled())

log.debug("Calling startup class " +method);

method.invoke(catalinaDaemon, param);

}

Catalina的load方法的实现见代码清单2。

代码清单2

/*** Start a new server instance.*/publicvoidload() {longt1 =System.nanoTime();

initDirs();//Before digester - it may be neededinitNaming();//Create and execute our DigesterDigester digester =createStartDigester();

InputSource inputSource=null;

InputStream inputStream=null;

File file=null;try{

file=configFile();

inputStream=newFileInputStream(file);

inputSource=newInputSource("file://" +file.getAbsolutePath());

}catch(Exception e) {//Ignore}if(inputStream ==null) {try{

inputStream=getClass().getClassLoader()

.getResourceAsStream(getConfigFile());

inputSource=newInputSource

(getClass().getClassLoader()

.getResource(getConfigFile()).toString());

}catch(Exception e) {//Ignore}

}//This should be included in catalina.jar//Alternative: don't bother with xml, just create it manually.if( inputStream==null) {try{

inputStream=getClass().getClassLoader()

.getResourceAsStream("server-embed.xml");

inputSource=newInputSource

(getClass().getClassLoader()

.getResource("server-embed.xml").toString());

}catch(Exception e) {//Ignore}

}if((inputStream ==null) && (file !=null)) {

log.warn("Can't load server.xml from " +file.getAbsolutePath());if(file.exists() && !file.canRead()) {

log.warn("Permissions incorrect, read permission is not allowed on the file.");

}return;

}try{

inputSource.setByteStream(inputStream);

digester.push(this);

digester.parse(inputSource);

inputStream.close();

}catch(Exception e) {

log.warn("Catalina.start using "

+ getConfigFile() + ": ", e);return;

}//Stream redirectioninitStreams();//Start the new servertry{

getServer().init();

}catch(LifecycleException e) {if(Boolean.getBoolean("org.apache.catalina.startup.EXIT_ON_INIT_FAILURE"))thrownewjava.lang.Error(e);elselog.error("Catalina.start", e);

}longt2 =System.nanoTime();if(log.isInfoEnabled())

log.info("Initialization processed in " + ((t2 - t1) / 1000000) + " ms");

}

这里对代明清单2进行分析,其执行步骤如下:

1) initDirs方法用于对catalina.home和catalina.base的一些检查工作。

2) initNaming方法给系统设置java.naming.factory.url.pkgs和java.naming.factory.initial。在创建JNDI上下文时,使用Context.INITIAL_CONTEXT_FACTORY("java.naming.factory.initial")属性,来指定创建JNDI上下文的工厂类;Context.URL_PKG_PREFIXES("java.naming.factory.url.pkgs")用在查询url中包括scheme方法id时创建对应的JNDI上下文,例如查询"java:/jdbc/test1"等类似查询上,即以冒号":"标识的shceme。Context.URL_PKG_PREFIXES属性值有多个java 包(package)路径,其中以冒号":"分隔各个包路径,这些包路径中包括JNDI相关实现类。当在JNDI上下文中查找"java:"这类包括scheme方案ID的url时,InitialContext类将优先查找Context.URL_PKG_PREFIXES属性指定的包路径中是否存在 scheme+"."+scheme + "URLContextFactory"工厂类(需要实现ObjectFactory接口),如果存在此工厂类,则调用此工厂类的getObjectInstance方法获得此scheme方案ID对应的jndi上下文,再在此上下文中继续查找对应的url。

3) createStartDigester方法创建并配置将要用来启动的Digester实例,并且设置一系列Rule,具体映射到server.xml。

4) 使用FileInputStream获取conf/server.xml配置文件输入流。

5) 将FileInputStream封装为InputSource,并且调用Digester的parse方法进行解析。

6) initStreams对输出流、错误流重定向。

7) 初始化server,具体实现本文不做分析。

总结从上面的分析可以看到,tomcat加载server.xml配置文件的方式,非常传统,正是使用FileInputStream进行加载的。有关server.xml配置文件的解析会在之后补充。

 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
 
© 2005- 王朝網路 版權所有 導航