设为首页 收藏本站
查看: 851|回复: 0

[经验分享] Tomcat源码分析之JNDI

[复制链接]

尚未签到

发表于 2017-1-22 10:31:23 | 显示全部楼层 |阅读模式
  在tomcat服务器中,我们可以通过配置文件%CATALINA_HOME%/conf/server.xml来对所用到的资源进行配置,如代码:
Xml代码

查看复制到剪切板打印





Xml代码 DSC0000.gif






<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,然后再进行。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-331968-1-1.html 上篇帖子: JDK+Myeclipse+Tomcat安装步骤 下篇帖子: TOMCAT 6数据源配置
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表