1.什么是JNDI?
JNDI( Java Naming and Directory Interface ),是Java平台的一个标准扩展,提供了一组接口、类和关于命名空间的概念。如同其它很多Java技术一样,JDNI是provider-based的技术,暴露了一个
API和一个服务供应接口(SPI)。这意味着任何基于名字的技术都能通过JNDI而提供服务,只要JNDI支持这项技术。JNDI目前所支持的技术包括 LDAP、CORBA Common Object Service(COS)名字服务、RMI、NDS、DNS、Windows注册表等等。
很多J2EE技术,包括EJB都依靠JNDI来组织和定位实体。可以把它理解为一种将对象和名字捆绑的技术(就像是字典类型,有key和value),对象工厂负责生产出对象,这些对象都和唯一的名字绑在一起,外部资源可以通过名字获得某对象的引用。
2.为什么要使用JDI?
我们可以从“如果不用JNDI我们怎样做?用了JNDI后我们又将怎样做?“两个问题来比较,请看下面的例子(以连接数据库的例子为例):
1)在不适用JNDI的情况下:
Connection conn=null;
try {Class.forName("com.mysql.jdbc.Driver",
true, Thread.currentThread().getContextClassLoader());
conn=DriverManager.getConnection("jdbc:mysql://MyDBServer?user=qingfeng&password=mingyue");
......
conn.close();
}
catch(Exception e) {
e.printStackTrace();
}
finally {
if(conn!=null) {
try {
conn.close();
} catch(SQLException e) {}
}
}
2)在使用JNDI的情况下:
首先应先配置数据源:
<?xml version="1.0" encoding="UTF-8"?>
<datasources><local-tx-datasource>
<jndi-name>MySqlDS </jndi-name>
<connection-url>jdbc:mysql://localhost:3306/lw </connection-url>
<driver-class>com.mysql.jdbc.Driver </driver-class>
<user-name>root </user-name>
<password>rootpassword </password>
<exception-sorter-class-name>org.jboss.resource.adapter.jdbc.vendor.MySQLExceptionSorter </exception-sorter-class-name>
<metadata>
<type-mapping>mySQL </type-mapping>
</metadata>
</local-tx-datasource>
</datasources>
在程序中引用数据源:
Connection conn=null;
try {
Context ctx=new InitialContext();Object datasourceRef=ctx.lookup("java:MySqlDS"); //引用数据源DataSource ds=(Datasource)datasourceRef;conn=ds.getConnection();......c.close();
}catch(Exception e) {
e.printStackTrace();
}
finally {
if(conn!=null) {try {conn.close();} catch(SQLException e) { }}
}
通过上面两种情况的对比可以得到:使用JNDI后的程序可以不用关心具体JDBC参数了。在系统部署后,如果数据库的相关参数变更,只需要重新配置
mysql-ds.xml 修改其中的JDBC参数,只要保证数据源的名称不变,那么程序源代码就无需修改。由此可见,JNDI避免了程序与数据库之间的紧耦合,使应用更加易于配置、易于部署。
3.如何使用JNDI?
在javax.naming的包包中提供Context接口,提供了两个很好用的方法: <1> void bind( String name , Object object ) 将名称绑定到对象。所有中间上下文和目标上下文(由该名称最终原子组件以外的其他所有组件指定)都必须已经存在。 <2>Object lookup( String name ) 检索指定的对象。如果 name为空,则返回此上下文的一个新实例(该实例表示与此上下文相同的命名上下文,但其环境可以独立地 进行修改,而且可以并发访问)。
例如下面的一个例子:从JNDI名称空间存储和检索对象
- import javax.naming.*;
- public void createName() throws NamingException {
- Context context= new InitialContext();
- context.bind("/config/applicationName", "MyApp");
- }
- public String getName() throws NamingException {
- Context context= new InitialContext();
- return (String)context.lookup("/config/applicationName");
- }