JNDI的目的是什么


Answers:


109

JNDI是Java命名和目录接口。它用于分离应用程序开发人员和应用程序部署人员的关注点。在编写依赖于数据库的应用程序时,无需担心用于连接该数据库的用户名或密码。JNDI允许开发人员为数据库命名,并依靠部署者将该名称映射到数据库的实际实例。

例如,如果您要编写在Java EE容器中运行的代码,则可以编写此代码来获取JNDI名称为“ Database”的数据源:


DataSource dataSource = null;
try
{
    Context context = new InitialContext();
    dataSource = (DataSource) context.lookup("Database");
}
catch (NamingException e)
{
    // Couldn't find the data source: give up
}

请注意,这里没有关于数据库驱动程序,用户名或密码的任何信息。那是在容器内部配置的。

JNDI不限于数据库(JDBC);各种服务都可以命名。有关更多详细信息,请查看Oracle的教程


10
因此,在此示例中,JNDI与将数据库名称放入配置xml文件或属性文件然后从那里读取文件有何不同?
Ajay)

11
首先,您必须将密码以纯文本格式存储在配置文件中。其次,如果您有多个应用程序指向同一个数据库,并且有关数据库配置的更改,则必须在多个位置更新配置。
西蒙·尼克森

1
好吧,JNDI在这里有何帮助?
阿贾伊(Ajay)

1
无论是在J2EE上下文还是JavaSE上下文中,它都应包含您需要了解的有关JNDI的所有信息。javaworld.com/javaworld/jw-04-2002/jw-0419-jndi.html
Nico,2009年

5
@SimonNickerson嗨!我正在学习JNDI。这是一个很好的答案,但是如果您注意到问题“如何实现JNDI的使用?” 那么看起来还没完成。您从开发人员的角度描述了实现。部署者的观点如何?
lxknvlk

30

JNDI是一种非常强大的机制,可用于通过使用组织配置信息以及发现和侦听服务EventContext。在JNDI中,假设您的JNDI服务提供者支持它,则您可以查找和收听任何对象(不仅仅是DataSources)。

当然,唯一的问题实际上是拥有JNDI服务提供商。这样做的好处是,您可以轻松地自己滚动。毕竟,您可以将任何Java实例编码为XML使用JavaBeans XMLEncoderXMLDecoder:无需依赖在应用程序服务器中运行!

那么,这与配置文件有什么区别?好吧,因为您所有的应用程序都可以从同一位置获取其配置,因此它可以使操作更加简洁。如果他们需要共享配置信息(例如数据库位置),则可以在JNDI中定义一次。假设您移动了数据库服务器:您无需记住其中位置的繁琐的配置文件。您只需要去一个地方:JNDI。


这是迄今为止最全面的说明-谢谢oxbow_lakes!顺便说一句,您是否会按照您的建议在代码指针中编码任何Java实例?
罗汉·库玛

13

JNDI是用于访问目录和命名服务(即,名称与对象关联的方法)的API。名称与对象的关联称为绑定。

DNS是命名服务的一个基本示例,该DNS将计算机名称映射到IP地址。

使用JNDI,应用程序可以存储和检索任何类型的命名Java对象。

在Java上下文中,可以将其用于不需要硬编码特定于环境的变量的配置文件中。

春季示例:

Spring上下文文件

<bean id="WSClientConfig" class="com.example.BaseClientConfigImpl">
<property name="protocol">
    <jee:jndi-lookup jndi-name="java:comp/env/protocol" />
</property>
<property name="endpoint">
    <jee:jndi-lookup jndi-name="java:comp/env/endpoint" />
</property>
<property name="requestPath">
<jee:jndi-lookup jndi-name="java:comp/env/requestPath" />    
</property>

Tomcat上下文文件

<Environment name="protocol" type="java.lang.String" value="https://"/>
<Environment name="endpoint" type="java.lang.String" value="172.0.0.1"/>
<Environment name="requestPath" type="java.lang.String" value="/path/to/service"/>

3

JNDI允许将资源构造简化为名称。因此,为了方便/安全/其他原因,将许多细节分组为1。(又名抽象层)

实现: 设置一个属性列表,该列表与Jndi Context Interface中的预定义字段相对应。(这些属性指定了jndi执行的设置;但*不是搜索名称)

Properties props = new Properties();
//field Context.INITIAL_CONTEXT_FACTORY => property name java.naming.factory.initial
    //field Context.PROVIDER_URL => property name java.naming.provider.url
props.load(new FileInputStream("*properties file*")); //prop file in this case

Context ctx = new InitialContext(props);
    Object o = ctx.lookup("*name of resource*");

理想情况下,将存在一个专门的功能来在您的组织中维护LDAP目录,DNS等(因此,统一的单个映射集可为所有服务,从而减少差异)

JNDI服务提供商列表:https : //www.ibm.com/support/knowledgecenter/zh/SSVSD8_8.4.1/com.ibm.websphere.dtx.adapjndi.doc/concepts/c_jndi_JNDI_Service_Providers_.htm

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.