JNDI – What Is java:comp/env? – JNDI – 什么是 java:comp/env?

最后修改: 2023年 11月 5日

中文/混合/英文(键盘快捷键:t)

1. Overview

1.概述

The Java Naming and Directory Interface (JNDI) is an Application Programming Interface (API) that provides naming and directory services to Java-based applications. We can use this interface to bind objects/resources, look up or query objects, and detect changes on the same objects.

Java 命名和目录接口(JNDI)是一个应用程序编程接口(API),为基于 Java 的应用程序提供命名和目录服务。我们可以使用该接口绑定对象/资源、查找或查询对象,以及检测相同对象的变化。

In this tutorial, we’ll look specifically into the background behind using the “java:comp/env” standard prefix in the JNDI naming.

在本教程中,我们将具体介绍在 JNDI 命名中使用”java:comp/env“标准前缀的背景

2. What Is the Java Naming and Directory Interface?

2.什么是 Java 命名和目录接口?

In simple terms, a Naming Service is an interface to associate names with objects and, subsequently, find those objects with the help of names. As such, the Naming Service maintains a set of bindings that maps names with objects.

简单地说,命名服务是一个接口,用于将名称与对象关联起来,然后借助名称查找这些对象。因此,命名服务维护着一组将名称与对象进行映射的绑定。

The JNDI API enables the application components and the clients to look up the distributed resources, services, and EJB.

JNDI API 使应用程序组件和客户端能够查找分布式资源、服务和 EJB。

3. Accessing the Naming Context

3.访问命名上下文

The Context interface provides access to the naming environment. Using this object, we can bind names to objects, rename objects, and list the bindings. Let’s see how to get the context:

Context 接口提供了对命名环境的访问。使用该对象,我们可以将名称绑定到对象、重命名对象并列出绑定。让我们看看如何获取上下文:

JndiTemplate jndiTemplate = new JndiTemplate();
context = (InitialContext) jndiTemplate.getContext();

Once we have the context, we can bind the object:

获得上下文后,我们就可以绑定对象了:

context.bind("java:comp/env/jdbc/datasource", ds);

Then, we can retrieve the objects present in the context:

然后,我们就可以检索上下文中存在的对象:

context.lookup("java:comp/env/jdbc/datasource");

4. What Is java:comp/env?

4.什么是 java:comp/env?

As seen in the earlier example, we bind a name with a standard prefix “java:comp/env“. In our case, it’s “java:comp/env/jdbc/datasource” and not just “jdbc/datasource“. Is this prefix mandatory? Can we avoid it completely? Let’s discuss.

如前面的示例所示,我们绑定了一个带有标准前缀”java:comp/env“的名称。在我们的例子中,它是”java:comp/env/jdbc/datasource“,而不仅仅是”jdbc/datasource“。这个前缀是强制性的吗?我们能完全避免它吗?让我们来讨论一下。

4.1. Directory Service

4.1.目录服务

JNDI, as the name indicates, is a Naming and Directory service. Accordingly, a directory service associates names with objects and also permits such objects to have attributes. Hence, we not only can look up an object by its name but also get the object’s attributes or find the object based on its attributes. A live example is a telephone directory service where a subscriber’s name is mapped not only to his phone number but also to his address.

顾名思义,JNDI 是一种命名和目录服务。因此,目录服务将名称与对象关联起来,并允许这些对象具有属性。因此,我们不仅可以通过名称查找对象,还可以获得对象的属性或根据属性查找对象。一个活生生的例子就是电话簿服务,在该服务中,用户的姓名不仅映射到其电话号码,还映射到其地址。

Directories often arrange the objects in a hierarchy. In most cases, directory objects are stored in a tree structure. So, the first element/node might contain group objects that might, in turn contain specific objects.

目录通常按层次结构排列对象。在大多数情况下,目录对象以树形结构存储。因此,第一个元素/节点可能包含组对象,而组对象又可能包含特定对象。

For instance, in “java:comp/env” the “comp” element is the first node, and on the next level, it contains the “env” element. From here, we can store or access the resources based on our convention. For example, “jdbc/datasource” to share a data source object.

例如,在”java:comp/env“中,”comp“元素是第一个节点,下一层包含”env“元素。在这里,我们可以根据惯例存储或访问资源。例如,使用”jdbc/datasource“共享数据源对象。

4.2. The Split-up

4.2.分拆

Let’s break up our previous naming example: “java:comp/env/jdbc/datasource“.

让我们拆分一下之前的命名示例:”java:comp/env/jdbc/datasource“。

  • java is just like “jdbc:” from the JDBC connection string. It acts as a protocol.
  • comp is the root of all JNDI contexts. It’s bound to a subtree reserved for component-related bindings. The name “comp” is short for component. There are no other bindings in the root context.
  • env the name “env” is bound to a sub-tree that is reserved for the component’s environment-related bindings. “env” is short for environment.
  • jdbc is the subcontext for jdbc resources. There are other types, or sub-contexts for connection factories.
  • datasource is the name of our JDBC resource.

Here, except the last element, all other parent elements are standard names and thus can’t be changed.

在这里,除了最后一个元素外,所有其他父元素都是标准名称,因此不能更改

In addition, the root context is reserved for the future expansion of the policy. Specifically, this applies to naming resources that aren’t tied to the component itself but to other types of entities, such as users or departments. For example, future policies might allow us to name users and organizations/departments by using names such as “java:user/Anne” and “java:org/finance“.

此外,根上下文还为策略的未来扩展预留了空间。具体来说,这适用于与组件本身无关,而是与其他类型实体(如用户或部门)相关的资源命名。例如,未来的策略可能允许我们使用”java:user/Anne”和”java:org/finance“等名称来命名用户和组织/部门。

5. Relative vs. Absolute Paths

5.相对路径与绝对路径

In case we want to use a shorter version of JNDI lookup, we can do it with the help of sub-context. This way, we don’t need to mention the full path (absolute path) of the naming, but a relative path of the sub-context.

如果我们想使用较短版本的 JNDI 查找,可以借助子上下文来实现。这样,我们就不需要提及命名的完整路径(绝对路径),而是子上下文的相对路径。

We can derive a sub-context from the InitialContext object so that we don’t have to repeat the “java:comp/env” for every resource we retrieve:

我们可以从 InitialContext 对象派生出一个子上下文,这样我们就不必为检索的每个资源重复输入”java:comp/env“:

Context subContext = (Context) context.lookup("java:comp/env");
DataSource ds = (DataSource) subContext.lookup("jdbc/datasource");

As we can see here, we created a sub-context that holds the values inside “java:comp/env” and then used this sub-context (relative path) to look up the specific namings within it.

正如我们在这里看到的,我们创建了一个子上下文来保存”java:comp/env“中的值,然后使用这个子上下文(相对路径)来查找其中的特定命名。

6. Conclusion

6.结论

In this article, we quickly went through what is JNDI and its use cases. Then, we saw how to bind a JNDI name to the context and look up the same.

在本文中,我们快速了解了什么是 JNDI 及其用例。然后,我们了解了如何将 JNDI 名称绑定到上下文并查找相同内容。

Subsequently, we saw the split-up of the standard prefix: “java:comp/env” and the reason for using this prefix in JNDI naming. We also noted that the future policies might well expand both the root context “comp” and the sub-context “env“.

随后,我们看到了标准前缀的拆分:”java:comp/env“以及在 JNDI 命名中使用该前缀的原因。我们还注意到,未来的政策很可能会扩展根上下文”comp“和子上下文”env“。

As always, all code samples used in this article are available over on GitHub.

一如既往,本文中使用的所有代码示例均可在 GitHub 上获取。