此接口表示命名上下文,该命名上下文由一组名称到对象绑定组成。
它包含检查和更新这些绑定的方法。
名称
作为参数传递给Context方法的每个名称都与该上下文相关。
空名称用于命名上下文本身。
name参数可能永远不会为null。
大多数方法都有重载版本,其中一个采用Name参数,一个采用String 。 这些重载版本是等效的,如果Name和String参数只是同一名称的不同表示,则相同方法的重载版本的行为相同。 在下面的方法描述中,只有一个版本已完整记录。 第二个版本的链接指向第一个版本:相同的文档适用于两者。
对于支持联合的系统, String Context方法的名称参数是复合名称。 名称是的实例参数CompositeName被视为复合名称,而Name参数不属于的实例CompositeName作为化合物名称治疗(其可能是实例CompoundName或化合物名称的其它实施方式)。 这允许NameParser.parse()的结果用作Context方法的参数。 在JNDI 1.2之前,所有名称参数都被视为复合名称。
此外,对于支持联合的系统, NamingEnumeration从list()和listBindings()返回的所有名称都是表示为字符串的复合名称。 有关名称的字符串语法,请参阅CompositeName 。
对于不支持联合的系统,名称参数(在Name或String表单中)和NamingEnumeration返回的名称可以是它们自己的命名空间中的名称,而不是复合命名空间中的名称,由服务提供商自行决定。
例外
此接口中的所有方法都可以抛出NamingException或其任何子类。
有关每个异常的详细信息,请参阅NamingException及其子类。
并发访问
不保证Context实例与多个线程的并发访问同步。
需要同时访问单个Context实例的线程应该在它们之间进行同步并提供必要的锁定。
每个操作不同Context实例的多个线程无需同步。
请注意,传递空名称时, lookup方法将返回表示相同命名上下文的新Context实例。
出于并发控制的目的,在枚举仍在使用中,或者仍然遵循该操作生成的任何引用时,不会认为返回NamingEnumeration的上下文操作已完成。
参数
传递给Context接口的任何方法或其子接口之一的Name参数将不会被服务提供商修改。
服务提供者可以在操作期间保持对它的引用,包括方法结果的任何枚举和生成的任何引用的处理。
在此期间,调用者不应修改对象。
由任何此类方法返回的Name由调用者拥有。
呼叫者可以随后对其进行修改;
服务提供商可能不会。
环境属性
JNDI应用程序需要一种方法来传递各种首选项和属性,这些首选项和属性定义了访问命名和目录服务的环境。 例如,上下文可能需要指定安全凭证才能访问服务。 另一个上下文可能需要提供服务器配置信息。 这些被称为上下文的环境 。 Context接口提供了检索和更新此环境的方法。
当上下文方法从一个上下文继续到下一个上下文时,环境从父上下文继承。 对一个上下文的环境的更改不会直接影响其他上下文的环境。
当使用和/或验证环境属性的有效性时,它依赖于实现。 例如,服务提供商使用一些与安全相关的属性来“登录”目录。 此登录过程可能在创建上下文时发生,也可能在第一次在上下文中调用方法时发生。 何时以及是否发生这种情况取决于实现。 在上下文中添加或删除环境属性时,验证更改的有效性将再次依赖于实现。 例如,某些属性的验证可能在更改时发生,或者在对上下文执行下一个操作时发生,或者根本不发生。
任何引用上下文的对象都可以检查该上下文的环境。 敏感信息(如明文密码)不应存储在那里,除非已知实施保护它。
资源文件
为了简化设置JNDI应用程序所需的环境的任务,应用程序组件和服务提供者可以与资源文件一起分发。 JNDI资源文件是属性文件格式的文件(请参阅java.util.Properties ),其中包含键/值对的列表。 键是属性的名称(例如“java.naming.factory.object”),值是为该属性定义的格式的字符串。 以下是JNDI资源文件的示例:
java.naming.factory.object=com.sun.jndi.ldap.AttrsToCorba:com.wiz.from.Person java.naming.factory.state=com.sun.jndi.ldap.CorbaToAttrs:com.wiz.from.Person java.naming.factory.control=com.sun.jndi.ldap.ResponseControlFactory
JNDI类库读取资源文件并使属性值可以自由使用。
因此,JNDI资源文件应被视为“世界可读”,并且不应存储诸如明文密码之类的敏感信息。
JNDI资源文件有两种: 提供者和应用程序 。
提供者资源文件
每个服务提供商都有一个可选资源,列出了该提供商特有的属性。
该资源的名称是:
[ prefix/] jndiprovider.properties
其中prefix是提供者的上下文实现的包名称,每个句点(“。”)都转换为斜杠(“/”)。
例如,假设服务提供者定义了类名为com.sun.jndi.ldap.LdapCtx的上下文实现。
此提供程序的提供程序资源名为com/sun/jndi/ldap/jndiprovider.properties 。
如果类不在包中,则资源的名称只是jndiprovider.properties 。
JNDI类库中的某些方法使用指定JNDI工厂列表的标准JNDI属性:
java.naming.factory.object
java.naming.factory.state
java.naming.factory.control
java.naming.factory.url.pkgs
在确定这些属性的值时,JNDI库将查询提供程序资源文件。
可以在服务提供商的判断下在提供者资源文件中设置除这些之外的属性。
服务提供商的文档应明确说明允许的属性;
文件中的其他属性将被忽略。
应用资源文件
部署应用程序时,它的类路径中通常会有几个代码库目录和JAR。
JNDI在类路径中找到(使用ClassLoader.getResources() )名为jndi.properties所有应用程序资源文件 。
此外,如果Java安装目录包含内置属性文件(通常为conf/jndi.properties ,则JNDI会将其视为其他应用程序资源文件。
这些文件中包含的所有属性都放在初始上下文的环境中。
然后,此环境将由其他上下文继承。
对于在多个应用程序资源文件中找到的每个属性,JNDI使用找到的第一个值,或者在有意义的情况下,它会连接所有值(详细信息如下所示)。 例如,如果在三个jndi.properties资源文件中找到“java.naming.factory.object”属性,则对象工厂列表是来自所有三个文件的属性值的串联。 使用此方案,每个可部署组件都负责列出它导出的工厂。 在搜索工厂类时,JNDI会自动收集并使用所有这些导出列表。
属性搜索算法
当JNDI构造初始上下文时,将使用传递给构造函数,系统属性和应用程序资源文件的environment参数中定义的属性初始化上下文的环境。
然后,此初始环境将由其他上下文实例继承。
当JNDI类库需要确定属性的值时,它通过合并来自以下两个源的值按顺序执行:
正在运行的环境的环境。
正在操作的上下文的提供程序资源文件( jndiprovider.properties )。
对于在这两个源中找到的每个属性,JNDI确定属性的值如下。
如果该属性是指定JNDI工厂列表的标准JNDI属性之一(列为above ),则这些值将连接到单个以冒号分隔的列表中。
对于其他属性,仅使用找到的第一个值。
当服务提供者需要确定属性的值时,通常会直接从环境中获取该值。 服务提供者可以定义要在其自己的提供者资源文件中放置的特定于提供者的属性。 在这种情况下,它应该合并上一段中描述的值。
通过这种方式,每个服务提供者开发者可以指定与该服务提供者一起使用的工厂列表。 这些可以由应用程序的部署者指定的应用程序资源来修改,而应用程序资源又可以由用户修改。