浏览 3742 次
锁定老帖子 主题:Tomcat源码分析之JNDI
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2008-07-31
在tomcat服务器中,我们可以通过配置文件%CATALINA_HOME%/conf/server.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> 在这段配置中,指定了两个资源,一个是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,然后再进行。 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |