Java 为什么对数据源使用JNDI

Java 为什么对数据源使用JNDI,java,jndi,Java,Jndi,有人能解释为什么JNDI应该是公开数据库/jms等服务的首选方式吗 我遇到的帖子都谈到了不必加载特定的驱动程序管理器的优点,从连接池等中获益。但是,通过在属性文件中指定驱动程序管理器并使用反射,这是很容易实现的 连接池也可以通过spring或其他方式将正确的实现连接到应用程序bean中来实现 那么,为什么使用JNDI会更好呢?当您必须在不同环境之间移动应用程序时,JNDI真的会大放异彩:从开发到集成再到测试再到生产。如果将每个应用程序服务器配置为使用相同的JNDI名称,则可以在每个环境中使用不同

有人能解释为什么JNDI应该是公开数据库/jms等服务的首选方式吗

我遇到的帖子都谈到了不必加载特定的驱动程序管理器的优点,从连接池等中获益。但是,通过在属性文件中指定驱动程序管理器并使用反射,这是很容易实现的

连接池也可以通过spring或其他方式将正确的实现连接到应用程序bean中来实现


那么,为什么使用JNDI会更好呢?

当您必须在不同环境之间移动应用程序时,JNDI真的会大放异彩:从开发到集成再到测试再到生产。如果将每个应用程序服务器配置为使用相同的JNDI名称,则可以在每个环境中使用不同的数据库,而无需更改代码。您只需拿起WAR文件并将其放到新环境中

以下是判断这个答案时需要知道的一些其他假设:

  • 除了对日志的只读访问之外,我根本无法访问部署代码的服务器
  • 编写和打包代码的人员与配置和管理服务器的人员不同
  • 一旦一个WAR文件开始了它的PROD之旅,它就不能在不返回开始的情况下再次更改。如果WAR被更改,QA在测试服务器上进行的任何测试都必须重新进行
也许您没有看到这一好处,因为您是一个在本地桌面上编写代码并部署到生产环境的独立开发人员。

我认为“首选”机制是管理和配置人员首选的机制。正如duffymo所指出的,配置必须在可部署工件的外部,这一点至关重要,否则,我认为一切都会发生。如果您的系统管理员更喜欢使用GUI来配置JDNI条目,那就好了。如果他/她更喜欢用cssh和vi编辑属性文件,也很酷。如果你负责开发和配置/部署你的应用程序,那么这几乎就是你的职责。就个人而言,我喜欢在我的工件中保留尽可能多的实现,这意味着我的数据源和驱动程序也住在那里


如果您想了解JNDI相对于其他替代方案的技术优势,我不确定是否有,但您可能想澄清您的问题。

正如其他人所提到的,JNDI大部分用于服务位置查找,但主要用于类似DB的资源

最恼人的是Java的LDAP API也是JNDI API。使用LDAP时,抽象非常混乱。JNDI还有一个缺点,即有时是单点故障


通过使用主机名别名,您可以轻松完成JNDI的大部分工作。也就是说,在您的
/etc/hosts
(或您的env的任何位置)中创建一个别名,将MYRESOURCE指向
127.0.0.1
。然后在应用程序配置中使用MYRESOURCE作为主机名(例如,在jdbc url中)

然后,当您将应用程序移动到生产时,只需更改生产的
/etc/hosts
文件,将MYRESOURCE指向生产资源/服务(如prod数据库服务器)


以上是一种可移植性更强、占用空间更小的命名目录,可以在其他语言(ruby、python)中使用。它还可以处理JNDI通常无法完成的事情,比如REST服务。唯一恼人的是,您必须更新服务器主机文件,但这可以通过SSH脚本实现自动化。

JNDI相对于属性文件的真正好处在于部署到集群环境。使用属性文件可以使某些服务器实例具有不同的值。使用JNDI时,域控制器会将相同的值推送到所有群集服务器,从而无需将相同的属性文件复制到所有服务器(可能还会重新启动服务器/应用程序)。

JNDI帮助的另一个方面:

它抽象了资源的查找。通常,JNDI配置存储在应用服务器上的XML文件中,但不需要。例如,配置可能存储在LDAP服务器上,以便更容易集中维护


如果您运行的应用程序使用JNDI查找它们所需的内容,则可以从配置文件切换到使用LDAP服务器,而无需修改应用程序。如果每个应用程序都需要一个具有硬编码名称的属性文件,那么您就不走运了。想象一下,一个企业在生产中有几十个应用程序——将它们全部更改将是一个重大问题

换句话说,JNDI主要适用于复杂的部署场景,如:

  • 许多应用程序服务器(可能是群集的)
  • 许多不同的应用
  • 集中配置
  • 不同的服务器阶段(测试、生产)

因此,一开始它似乎有些过分,但在这些场景中非常有用。当然,有些好处甚至适用于小型部署,例如DB连接的标准化配置。

那么,这与在这些环境中使用属性文件有什么不同呢?毕竟,管理员正在管理每台服务器上的数据库连接。属性文件通常打包在WAR中,因此您无法更改它们。您必须按环境区分文件,并传递一个变量来标识您所在的位置。如果你真的被说服按自己的方式去做,一定要这样做。我不想卖任何东西;听起来你并不想承认任何不同。有些人只是希望自己的想法得到验证;也许你就是其中之一。当我在WAR文件中部署时,我总是这样做,我的类路径由WEB-INF/lib中的JAR和WEB-INF/classes下的包组成——就是这样。除非我为战争中的每一个环境都设置一个.properties文件,否则我无法更改任何内容