您如何实现 JNDI 的使用,如果可能的话,举个例子?
4 回答
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 的教程。
JNDI是一种非常强大的机制,用于组织配置信息以及通过使用EventContext
. 在 JNDI 中,您可以查找和侦听任何对象(不仅仅是DataSource
s),假设您的 JNDI 服务提供者支持它。
当然,唯一的问题实际上是拥有一个 JNDI 服务提供者。这样做的好处是它非常容易自己滚动。毕竟,您可以将任何 Java 实例编码为XML
使用 JavaBeansXMLEncoder
并且XMLDecoder
:您不需要依赖于在应用程序服务器中运行!
那么这个拥有配置文件有什么区别呢?好吧,它可以更干净,因为您的所有应用程序都可以从同一个地方获取它们的配置。如果他们需要共享配置信息(例如数据库位置),那么这可以在 JNDI 中定义一次。假设您移动了数据库服务器:您不需要记住其中包含位置的海量配置文件。您只需去一个地方:JNDI。
JNDI 是一种用于访问目录和命名服务(即名称与对象关联的方式)的 API。名称与对象的关联称为绑定。
命名服务的一个基本示例是 DNS,它将机器名称映射到 IP 地址。
使用 JNDI,应用程序可以存储和检索任何类型的命名 Java 对象。
在 java 的上下文中,这可以在您不想硬编码环境特定变量的配置文件中使用。
弹簧示例:
弹簧上下文文件
<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"/>
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 等(因此统一的单个映射集为所有服务提供服务,减少了差异)