在上一篇我们知道tomcat在启动时会解析context.xml并将相应的数据源信息解析到上下文中。那么接下来的工作就是如何去访问这个数据源信息了。我们访问数据源信息是通过以下代码进行访问的
InitialContext initialContext = new InitialContext(); DataSource dataSource = (DataSource) initialContext.lookup("java:comp/env/jdbc/xx");
那么我们就按照这个访问思路跟踪一下代码。我们看一下InitialContext的lookup实现,如下所示:
public Object lookup(String name) throws NamingException { return getURLOrDefaultInitCtx(name).lookup(name); }
这里会取得一个UrlContext或InitContext,究竟取得哪个取决于传递的参数信息,这里我们的方法是以java:开头,即它有一个scheme_id信息,按照官方对于传递的URL字符串规则,显示如下所示(该描述在javadoc中的InitialContext中):
解析 URL 字符串时生成此策略的一个异常,如下所述。 在将 URL 字符串(一个 scheme_id:rest_of_name 形式的 String)作为名称参数传递给任一方法时,将定位处理该方案的一个 URL 上下文工厂,并 将它用于解析该 URL。如果没有找到这样的工厂,则使用由 "java.naming.factory.initial" 指定的初始上下文。类似地,当将第一个组件是 URL 字 符串的 CompositeName 对象作为名称参数传递给任一方法时,将定位一个 URL 上下文工厂并将它用于解析第一个名称组件
因此,它将尝试找一个URLContext,而在前文中我们提到在tomcat支持命名服务中,设置了一个Context.URL_PKG_PREFIXES参数为org.apache.naming,因此,会尝试寻找一个名叫
org.apache.naming.java.javaURLContextFactory的类,而恰好存在这个类。那么InitContext将转向这个类,再从这个类找回一个UrlContext实例,具体实现如下所示: