什么是JNDI? 它的基本用途是什么? 什么时候使用?
当前回答
什么是JNDI ?
它代表Java命名和目录接口。
它的基本用途是什么?
JNDI允许分布式应用程序以抽象的、独立于资源的方式查找服务。
什么时候使用?
最常见的用例是在Java EE应用服务器上设置数据库连接池。部署在该服务器上的任何应用程序都可以使用JNDI名称java:comp/env/FooBarPool访问所需的连接,而无需了解有关连接的详细信息。
这有几个优点:
如果你有一个应用程序从devl->int->test->prod环境迁移的部署序列,你可以在每个环境中使用相同的JNDI名称,并隐藏实际使用的数据库。应用程序在环境之间迁移时不必更改。 您可以尽量减少需要知道访问生产数据库的凭据的人数。只有Java EE应用服务器需要知道您是否使用JNDI。
其他回答
JNDI在外行的术语中基本上是一个接口,用于获得内部/外部资源的实例,例如
javax.sql.DataSource,
javax.jms.Connection-Factory,
javax.jms.QueueConnectionFactory,
javax.jms.TopicConnectionFactory,
javax.mail.Session, java.net.URL,
javax.resource.cci.ConnectionFactory,
或由JCA资源适配器定义的任何其他类型。 它提供了一种能够创建访问的语法,无论访问是内部的还是外部的。例如(在这个例子中,comp/env的意思是组件/环境,有很多其他的语法):
jndiContext.lookup("java:comp/env/persistence/customerDB");
命名服务将名称与对象关联起来,并根据对象的给定名称查找对象。(RMI注册表是命名服务的一个很好的例子。)JNDI为许多现有的命名服务(如LDAP、DNS)提供了一个公共接口。
如果没有JNDI,远程资源的位置或访问信息必须硬编码在应用程序中或在配置中可用。维护这些信息非常繁琐,而且容易出错。
对我来说最好的解释在这里
什么是JNDI
它是一个API,用于提供对目录服务的访问,即服务映射名称(字符串)与对象、对远程对象或简单数据的引用。这叫做 绑定。绑定的集合称为上下文。应用程序使用JNDI接口访问资源。 简单地说,它就像一个带有String键和Object值的hashmap,表示web上的资源。
JNDI解决了什么问题
Without JNDI, the location or access information of remote resources would have to be hard-coded in applications or made available in a configuration. Maintaining this information is quite tedious and error prone. If a resources has been relocated on another server, with another IP address, for example, all applications using this resource would have to be updated with this new information. With JNDI, this is not necessary. Only the corresponding resource binding has to be updated. Applications can still access it with its name and the relocation is transparent.
Java命名和目录接口(JNDI)是一个应用程序编程接口(API),为使用JavaTM编程语言编写的应用程序提供命名和目录功能。它被定义为独立于任何特定的目录服务实现。因此,可以以通用的方式访问各种目录——新的、正在出现的和已经部署的目录。
尽管JNDI在轻量级、容器化的Java应用程序(如Spring Boot)中扮演的角色较少,但还有其他用途。仍然使用JNDI的三种Java技术是JDBC、EJB和JMS。它们在Java企业应用程序中都有广泛的用途。
例如,一个独立的DevOps团队可能在所有环境中管理敏感数据库连接的用户名和密码等环境变量。JNDI资源可以在web应用程序容器中创建,JNDI被用作在所有环境中工作的一致抽象层。
这种设置允许开发人员为开发目的创建和控制本地定义,同时通过相同的JNDI名称连接到生产环境中的敏感资源。
参考: https://docs.oracle.com/javase/tutorial/jndi/overview/index.html
我将使用一个示例来说明如何在应用程序开发人员不知道数据库用户名和密码的情况下使用JNDI来配置数据库。
1)我们已经在JBoss服务器的standalone-full.xml中配置了数据源。此外,我们还可以配置池的详细信息。
<datasource jta="false" jndi-name="java:/DEV.DS" pool-name="DEV" enabled="true" use-ccm="false">
<connection-url>jdbc:oracle:thin:@<IP>:1521:DEV</connection-url>
<driver-class>oracle.jdbc.OracleDriver</driver-class>
<driver>oracle</driver>
<security>
<user-name>usname</user-name>
<password>pass</password>
</security>
<security>
<security-domain>encryptedSecurityDomain</security-domain>
</security>
<validation>
<validate-on-match>false</validate-on-match>
<background-validation>false</background-validation>
<background-validation-millis>1</background-validation-millis>
</validation>
<statement>
<prepared-statement-cache-size>0</prepared-statement-cache-size>
<share-prepared-statements>false</share-prepared-statements>
<pool>
<min-pool-size>5</min-pool-size>
<max-pool-size>10</max-pool-size>
</pool>
</statement>
</datasource>
现在,这个jndi-name及其关联的数据源对象将对我们的application.application可用。
2)我们可以使用JndiDataSourceLookup类来检索这个数据源对象。
在我们提供jndi-name之后,Spring将实例化数据源bean。
现在,我们可以根据环境或需求更改池大小、用户名或密码,但这不会影响应用程序。
注意:encryptedSecurityDomain,我们需要在JBoss服务器中单独配置它
<security-domain name="encryptedSecurityDomain" cache-type="default">
<authentication>
<login-module code="org.picketbox.datasource.security.SecureIdentityLoginModule" flag="required">
<module-option name="username" value="<usernamefordb>"/>
<module-option name="password" value="894c8a6aegc8d028ce169c596d67afd0"/>
</login-module>
</authentication>
</security-domain>
这是其中一个用例。希望它能澄清。