`

Tomcat源码分析之JNDI

阅读更多

在tomcat服务器中,我们可以通过配置文件%CATALINA_HOME%/conf/server.xml来对所用到的资源进行配置,如代码:
Xml代码

Xml代码 复制代码
<GlobalNamingResources>
  <Resource
    name="UserDatabase"
    auth="Container"
    type="org.apache.catalina.UserDatabase"
    description="User database that can be updated and saved"
    factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
    pathname="conf/tomcat-users.xml" />
  <Resource
    name="jdbc/wroxTC6"
    auth="Container"
    type="javax.sql.DataSource"
    maxActive="20"
    maxIdle="30"
    maxWait="10000"
    username="root"
    password="1234"
    driverClassName="com.mysql.jdbc.Driver"
    url="jdbc:mysql://localhost:3306/test?autoReconnect=true" />
</GlobalNamingResources>
<GlobalNamingResources>
  <Resource
    name="UserDatabase"
    auth="Container"
    type="org.apache.catalina.UserDatabase"
    description="User database that can be updated and saved"
    factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
    pathname="conf/tomcat-users.xml" />
  <Resource
    name="jdbc/wroxTC6"
    auth="Container"
    type="javax.sql.DataSource"
    maxActive="20"
    maxIdle="30"
    maxWait="10000"
    username="root"
    password="1234"
    driverClassName="com.mysql.jdbc.Driver"
    url="jdbc:mysql://localhost:3306/test?autoReconnect=true" />
</GlobalNamingResources>



在这段配置中,指定了两个资源,一个是UserDatabase,另一个是jdbc/wroxTC6。本文主要讲述了,在tomcat是怎样通过JNDI来找到这些资源的。

1.JNDI基础和Tomcat中的JNDI
JNDI的全称是Java Naming and Directory Interface, JNDI的整体架构包含有JNDI API和JNDI SPI。利用前者可以访问各种Naming Services和Directory Services。

Service Providers利用JNDI SPI来编写这些服务。因此这些服务可以被Java应用灵活的插拔。

在JNDI中,用名字来标识一个服务对象,name和object之间建立的关联称为一个binding,binding的集合称作context。
javax.naming.Context是Naming Services所在的上下文接口;javax.naming.directory.DirContext是Directory Services所在的上下文接口。

在tomcat中类NamingContext实现了接口Context,在该类中保存有多个binding,每一个binding是一个 NamingEntry实例。对于NamingEntry分为4种类型:ENTRY、LINK_REF、REFERENCE和CONTEXT。
在tomcat中的配置文件service.xml中,可以为tomcat服务器配置全局的Naming Resource,也可以单独为某一个web应用配置局部的Naming Resource。

2.寻找被绑定的资源
在tomcat启动时,采用了责任链模式来进行。在启动StandardServer时,调用与之相关的监听器。在监听器NamingContextListener中,对全局的Naming Resources建立Context,绑定资源,查找资源等等。在启动StandardContext时,监听器NamingContextListener负责完成对局部Naming Resources相关操作。本文讲述对全局的Naming Resources的处理。

(1)首先是建立NamingContext类的实例:根Context(名字为:"/")

(2)将资源对象从NamingResources中取出,形成Reference,绑定到根Context中。

因为在加载配置文件时,利用tomcat中的Digester,已经将配置文件形成了类NamingResources的实例,也就是配置文件的信息已经形成了相应的NamingResources对象。从NamingResources实例中取出资源,建立ResourceRef实例。
ResourceRef继承了java.naming.Reference,该类并不是具体的Resource,也不做为binding中的object 加入到Context中。但是通过该对象,可以找到待绑定的Service,例如在UserDatabase所形成的ResourceRef实例中,指定的Reference的className是org.apache.catalina.UserDatabase;而配置文件的factory属性对应于一个StringRefAddr对象,加入到了Reference中。

将该Reference对象,形成REFERENCE类型的NamingEntry对象,并以资源的name属性为名称,加入根Context中。例如:以UserDatabase为名称,将该Resource对应的REFERENCE类型的NamingEntry对象,加入到了根Context中。

(3)从根Context查找资源,利用Reference找到资源。
当利用资源名称查找资源时,调用的是NamingContext.lookup方法。该方法中利用JNDI的方法NamingManager.getObjectInstance来调用Service Provider所提供的Service。
在方法NamingManager.getObjectInstance中,若传递的Reference不为空,则调用Reference的getFactoryClassName来获得具体的factory类(该factory类由Service Provider来实现,所以能够找到具体的资源。在Tomcat中,ResourceRef覆盖了getFactoryClassName方法,得到的是ResourceFactory实例)
调用ResourceFactory.getObjectInstance方法,从Reference的RefAddr中得到org.apache.catalina.users.MemoryUserDatabaseFactory实例,通过MemoryUserDatabaseFactory.getObjectInstance得到具体的资源MemoryUserDatabase对象。
(4)将真实的对象赋给NamingEntry的object属性,更改NamingEntry的类型为ENTRY。
此时根Context中存在有对真实的资源的绑定,名称为该资源的名称。

3.建立子Context
如果资源的名称中包含"/",则将REFERENCE类型的NamingEntry对象加入到Context前,要建立子Context。例如资源"jdbc/wroxTC6",需要建立子Context。

(1)建立子Context
建立子Context,并将该Context以CONTEXT类型的NamingEntry加入到根Context中。

(2)将资源对象从NamingResources中取出,形成Reference,绑定到子Context中。
在调用根Context对象的bind方法时,将资源的绑定委派到子Context中,将Reference绑定到子Context中。例如将资源"wroxTC6"绑定到以"jdbc"为名字的子Context中。

(3)查找资源,绑定真实的资源到子Context中。
在进行资源查找和找真实资源时,原理同2,只不过是首先找到子Context,然后再进行。

分享到:
评论

相关推荐

    JAVA上百实例源码以及开源项目源代码

    EJB中JNDI的使用源码例子 1个目标文件,JNDI的使用例子,有源代码,可以下载参考,JNDI的使用,初始化Context,它是连接JNDI树的起始点,查找你要的对象,打印找到的对象,关闭Context…… ftp文件传输 2个目标文件...

    JAVA上百实例源码以及开源项目

    EJB中JNDI的使用源码例子 1个目标文件,JNDI的使用例子,有源代码,可以下载参考,JNDI的使用,初始化Context,它是连接JNDI树的起始点,查找你要的对象,打印找到的对象,关闭Context…… ftp文件传输 2个目标文件...

    《程序天下:J2EE整合详解与典型案例》光盘源码

    2.3.2 使用MVC模式的不足之处 2.4 目前市场上常见的轻量级J2EE开发容器 2.5 小结 第二篇 建立和使用J2EE的开发平台 第三章 建立Java的开发平台 3.1 建立Java的开发环境 3.1.1 下载JDK 3.1.2 安装JDK 3.1.3 设定Path...

    搞定J2EE:STRUTS+SPRING+HIBERNATE整合详解与典型案例 (2)

    一共四个,其中pdf 三个包,源码一个包 第一章 J2EE快速入门 1.1 J2EE概述 1.1.1 J2EE的来源 1.1.2 J2EE整体框架 1.1.3 从J2EE到JavaEE 1.2 J2EE组件 1.2.1 客户端组件 1.2.2 Web组件 1.2.3 业务逻辑组件 1.3 J2EE...

    搞定J2EE:STRUTS+SPRING+HIBERNATE整合详解与典型案例 (1)

    一共四个,其中pdf 三个包,源码一个包 第一章 J2EE快速入门 1.1 J2EE概述 1.1.1 J2EE的来源 1.1.2 J2EE整体框架 1.1.3 从J2EE到JavaEE 1.2 J2EE组件 1.2.1 客户端组件 1.2.2 Web组件 1.2.3 业务逻辑组件 1.3 J2EE...

    搞定J2EE:STRUTS+SPRING+HIBERNATE整合详解与典型案例 (3)

    一共四个,其中pdf 三个包,源码一个包 第一章 J2EE快速入门 1.1 J2EE概述 1.1.1 J2EE的来源 1.1.2 J2EE整体框架 1.1.3 从J2EE到JavaEE 1.2 J2EE组件 1.2.1 客户端组件 1.2.2 Web组件 1.2.3 业务逻辑组件 1.3 J2EE...

    基于J2EE框架的个人博客系统项目毕业设计论文(源码和论文)

    Tomcat是一个免费的开源的Serlvet容器,在Tomcat中,应用程序的部署很简单,你只需将你的WAR放到Tomcat的webapp目录下,Tomcat会自动检测到这个文件,并将其解压。你在浏览器中访问这个应用的Jsp时,通常第一次会很...

    java 面试题 总结

    但通常情况下,由于Java Bean是被容器所创建(如Tomcat)的,所以Java Bean应具有一个无参的构造器,另外,通常Java Bean还要实现Serializable接口用于实现Bean的持久性。Java Bean实际上相当于微软COM模型中的本地...

    jpivot学习总结.doc

    controllerURL 否 String 是 链接到 JPivot Controller 的 URL ,该属性在一些复杂环境下比如 Portal 之类就很有用。 4.3. chooseQuery 从前面创建的若干个查询当中选择一个合适的查询(通过查询名称进行选择...

    超级有影响力霸气的Java面试题大全文档

    但通常情况下,由于Java Bean是被容器所创建(如Tomcat)的,所以Java Bean应具有一个无参的构造器,另外,通常Java Bean还要实现Serializable接口用于实现Bean的持久性。Java Bean实际上相当于微软COM模型中的本地...

Global site tag (gtag.js) - Google Analytics