是什么
前面说过了JNDI的概念
其实简单的说,java naming and directory Interface就是这样一种形式:提供命名和目录服务的API给开发者,把服务的实现留给各个厂商。而这个API提供的服务就是把名字翻译成一个对象,就像DNS服务把域名地址翻译成32位二进制IP地址一样。当然了还有一部分目录服务的功能,其实目录服务就是在命名服务的同时提供服务的查询与分类功能(对目录服务部分不理解没关系,以后再看LADP的时候就能真正理解了)
怎么用
上面提到了JNDI分API和实现两部分,API是留给开发者使用的,内容已经在jdk中给出,就在javax.naming.*包里面。而实现由不同厂商实现,其实就是各个应用服务器提供商,比如tomcat、weblogic、jetty等。通常我们使用jndi的场所就是配置数据源、JMS、EJB,而网上搜到最多的当然就是数据源的配置了。要理解JNDI并学会使用它看那些数据源的配置只会让你更迷糊,“不识庐山真面目,只缘身在此山中”。记住一句话,JNDI就是个翻译,通过一个字符串得到一个类,我们只需要配置好他们自己的关联关系,‘’什么字符串对应什么类由什么类创建就可以了‘’,配置在哪呢,各种应用服务器对我们提供这种服务的时候自然做了官方说明,举个例子tomcat(本文提到的tomcat基于tomcat6.0,据我所知7.0的配置跟6.0没区别,而5.5会有区别详细请看http://blog.youkuaiyun.com/heqingsong1/article/details/8539163):
首先,运行tomcat,保证你的tomcat的webapps目录下有docs这个默认给出的web项目。
第二,访问http://localhost:8080/docs/
第三,点击JNDI Resources链接,或者直接访问http://localhost:8080/docs/jndi-resources-howto.html
最后,这个页面介绍了JNDI在tomcat服务器中应该如何配置
至于如何把字符串翻译成你想要的对象,完全由weblogic这样的应用提供商实现。
常见的配置总结
大致总结一下网上关于数据源的JNDI配置,大致有3种,大多分3步。
第一步,配置”<Resouce 。。。 />”标签以及里面属性,这个就是我们想要通过字符串获取的对象类
第二步 ,配置web.xml文件获取相应的JNDI元素(其实就是上面的能够第一步配置的标签)
第三步,在程序中获取,Context initCtx = new InitialContext();
这是tomcat说明文档里面的一段代码,其中bean/MybeanFactory就是我们给出的字符串,然后获取到了Mybean的对象,“翻译”完成。
Context envCtx = (Context) initCtx.lookup("java:comp/env");
MyBean bean = (MyBean) envCtx.lookup("bean/MyBeanFactory");
刚刚说网上流传的JNDI配置大致有三种,其实绝大多数区别就在第一步中——到底在哪里配置”<Resouce 。。。/>”,大多数网上提到JNDI的配置的文章都没有提到,因为这个JNDI没有太大关系,属于tomcat的配置文件的作用范畴的知识点。
tomcat的配置文件都集中在conf文件夹里面,有server.xml context.xml tomcat-users.xml web.xml 以及两个properties文件——catalina和logging
catalina.properties是tomcat核心配置文件,它管理tomcat启动时关于类加载的包配置信息。logging.properties管理日志信息。tomcat-users.xml文件管理tomcat默认给出的manager这个web工程的user信息,manager工程其实是tomcat本身给自己的一个监控工程,能够控制自身的运行配置,监控当前tomcat下的所有运行中的工程。
而server.xml和context.xml是关于JNDI配置相关的两个配置文件。
第一种
在server.xml或context.xml里面的<context>标签里面配置<Resource>标签
而context.xml其实是server.xml文件中的一个元素<context>独立出来的扩展,也就是说你把<Resource>或者<ResourceLink>配置在server.xml文件的<Host>标签中的<context>标签中还是配置在context.xml文件中是一样的。唯一的区别就是context.xml可以在tomcat运行中进行动态扫描,而server.xml只能重启tomcat。http://blog.youkuaiyun.com/heqingsong1/article/details/8539163里面有详细解释。
第二种
一、
在server.xml的<GlobalNamingResources>标签里面配置<Resource>标签,第一种里面说的context是tomcat里面一共webproject上下文的概念,也就是一共web应用对应一个context,也就是局部配置,而这一种是全局配置(GlobalNamingResources)。这里有个需要注意的地方,除了要配置<ResourceLink>之外,如果哪个web context需要引用这个全局的Resource,需要在context里面配置<ResourceLink>标签,配置方式和第一种相似。
二、
如果你在context.xml文件里面配置的时候没有指定这个context是哪个web project的,也就是没有配置path等等属性,那么它就是全局的
第三种
一、
在META-INF文件夹里面新建一个context.xml文件然后写类似下面的配置信息
<?xml version="1.0" encoding="UTF-8"?>
<Context>
<Resource name="jndi/mybatis"
auth="Container"
type="javax.sql.DataSource"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/appdb"
username="root"
password="123456"
maxActive="20"
maxIdle="10"
maxWait="10000"/>
</Context>
显然这是每个context的局部配置。
二、
在tomcat的\conf\Catalina\localhost下(没有目录就新建)创建一个xml文件,文件名必须和项目名相同,加入测试JNDI数据源的web项目的项目名称是:JNDITest,所以xml文件的命名就叫JNDITest.xml
<?xml version="1.0" encoding="UTF-8"?>
<!--
jndi配置方法(tomcat):
将此文件放置在tomcat\conf\Catalina\localhost下(没有目录就新建)
-->
<!--映射JNDITest项目的虚拟目录-->
<Context docBase="D:/MyEclipse8.5/workspace/JNDITest/WebRoot" debug="0" reloadable="false">
<!--引用Oracle数据库的JNDI数据源-->
<ResourceLink name="oracleDataSource" global="jdbc/oracle" type="javax.sql.DataSource"/>
<!--引用mysql数据库的JNDI数据源-->
<ResourceLink name="mysqlDataSource" global="jdbc/mysql" type="javax.sql.DataSource"/>
<!--引用sqlserver数据库的JNDI数据源-->
<ResourceLink name="sqlserverDataSource" global="jdbc/sqlserver" type="javax.sql.DataSource"/>
</Context>
这里用的是<ResourceLink>标签,其实如果没有在server.xml文件的<GlobalNamingResources>里面配置<Resource>的话可以在这里直接配置<Resource>,这样就是局部配置了。
关于“一”和“二”配置,其实结果是一样的,tomcat会把META-INF文件夹里面的一个context.xml文件读取然后内容存储到tomcat\conf\Catalina\localhost\应用名.xml。这是tomcat的官方文档里面提到的,有图为证:
总结
其实理解这么多种配置的关键在于
1、理解tomcat关于server、service、host、context等元素的概念,特别是context。下面这篇文章做了比较详细的解释
http://blog.youkuaiyun.com/yuanxuegui2008/article/details/6056754
2、<ResourceLink>和<Resource>的区别其实就是一个是引用,一个实体配置。