5

在 Tomcat 中,您可以在 context.xml 中指定资源(JDBC 连接、Javax 邮件会话等),在 web.xml 中引用它们,然后在 Java 中加载它们,如下所示:

Context ctx = new InitialContext();
DataSource dataSource = (DataSource)ctx.lookup("java:/comp/env/jdbc/myDB");

我对这里发生的神奇 voo doo 很感兴趣!我本来预计需要InitialContext使用哈希表或其他对象注入构造函数,从而将其注入 context.xml 和 web.xml 中定义的所有内容。但它是一个无参数的构造函数!!!

所以我问:Tomcat 做了什么来填充 2 个 XML 文件和InitialContext无参数构造函数之间的“缺失链接”,以便从实例DataSource中神奇地可用?ctx提前致谢!

4

3 回答 3

10

正如您所描述的,魔法巫毒教有几个部分。

首先在启动过程的早期Tomcat调用:

System.setProperty(javax.naming.Context.INITIAL_CONTEXT_FACTORY,
        "org.apache.naming.java.javaURLContextFactory");

这告诉 JVM 使用 Tomcat 自己的工厂来创建 InitialContext 的实例。

第二部分基于这样一个事实,即每个 Web 应用程序都有自己的类加载器,并且所有用户代码都使用设置为线程上下文类加载器的类加载器执行。因此,当创建一个新的 InitialContext 时,Tomcat 可以查看线程上下文类加载器来确定哪个 Web 应用程序正在发出请求。

从那里开始,将新的 InitialContext 对象与当前应用程序的正确 JNDI 资源集挂钩是一个简单的过程。

于 2013-07-10T22:07:59.913 回答
6

在启动时,tomcat 读取context.xml并创建在那里定义的所有资源,并将它们注册到它的 JNDI 上下文中。您发布的代码只是获取这些资源的方式。

web.xml(在部署 Web 应用程序时读取)中,定义的资源不是全新的。这些是 Web 应用程序本地的,但将指向context.xml. 这样做的目的是让您的 Web 应用程序中的 Java 代码可以间接查找服务器资源。

于 2013-07-10T14:47:04.667 回答
4

根据Tomcat文档

InitialContext 配置为最初部署的 Web 应用程序,并且可供 Web 应用程序组件使用(用于只读访问)。

如果我不得不猜测,他们只是读取您的配置文件($CATALINA_BASE/conf/server.xml等)的静态位置,并在部署时为每个 Web 应用程序提供它。该文档还详细介绍了每个文件的每种类型的条目以及如何处理每个条目。

查看IntialContext.java的源代码,您对 HashTable 的预感是正确的,它确实有一个构造函数,并且似乎将条目存储在 HashTable myProps 中。

于 2013-07-10T14:44:12.920 回答