如果可能,如何举例说明如何实现JNDI的用法?
Answers:
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中,假设您的JNDI服务提供者支持它,则您可以查找和收听任何对象(不仅仅是DataSource
s)。
当然,唯一的问题实际上是拥有JNDI服务提供商。这样做的好处是,您可以轻松地自己滚动。毕竟,您可以将任何Java实例编码为XML
使用JavaBeans XMLEncoder
和XMLDecoder
:无需依赖在应用程序服务器中运行!
那么,这与配置文件有什么区别?好吧,因为您所有的应用程序都可以从同一位置获取其配置,因此它可以使操作更加简洁。如果他们需要共享配置信息(例如数据库位置),则可以在JNDI中定义一次。假设您移动了数据库服务器:您无需记住其中位置的繁琐的配置文件。您只需要去一个地方:JNDI。
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"/>
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