JavaEE命名服务与JNDI

来源:互联网 发布:淘宝上新速度 编辑:程序博客网 时间:2024/04/30 21:09

JavaEE应用往往需要访问数据库、JMS服务等各种资源。相对于JavaEE应用来说,一个具体的资源就是一个能够提供连接数据库服务器或JMS消息系统的对象。每个资源都有一个唯一的的名字作为标识,这个名字就是JNDI命名

JNDI (Java Naming and DirectoryInterface)就是Java命名服务的标准接口。从JavaEE 7的标准体系开始JNDI已经成为JavaSE的组成部分,以命名与目录服务的形式提供给应用。

在JavaEE服务器中,资源首先在服务器的容器中配置,然后通过命名与目录服务将资源及其JNDI命名绑定在一起发布,JavaEE应用不必考虑资源库的具体类型和配置参数,只要通过JNDI命名就可以找到对应的资源,并进而访问具体的资源。JNDI为JavaEE应用提供了一种统一的、松耦合的定位并访问资源的方式

1. JNDI的命名空间

显然,应用能够访问资源的前提条件是必须首先通过JNDI命名找到需要的资源,而且这种JNDI的命名必须遵守统一的命名规范。为了区分JNDI命名的作用范围,命名与目录服务将JNDI命名的环境上下文划分为若干个命名空间,将资源及其JNDI命名以“name/object”对的形式加入到命名空间中,从而实现资源的JNDI发布并供应用查找访问

JavaEE提供了如下4种标准的命名空间:

  • java:comp,当前组件范围内有效的命名空间,如服务器提供的默认JDBC数据源、默认JMS连接工厂等
  • java:module,当前类库模块范围内有效的命名空间
  • java:app,当前应用范围内有效的命名空间
  • java:global,整个服务器范围内有效的命名空间

除了上述4种标准的命名空间,WildFly还另外提供了如下2种命名空间,他们都在整个服务器范围内有效:

  • java:/
  • java:jboss

其中可供远程JNDI访问的命名空间是java:jboss的子空间java:jboss/exported。


2. WildFly服务器提供了如下4种发布JNDI命名的方式:

  • 在web.xml文件中使用<env-entry>元素
  • 在standalone.xml文件中配置naming子系统
  • 使用标准的JNDI API
  • 标准的JNDI API的基础上结合使用WildFly的Modules/Extensions API

3.JNDI命名的查找

JavaEE应用中查找JNDI命名的方式有多种,具体可以分为在本地(服务器上)查找和在远程(服务器上)查找。

1) 对于本地JNDI命名查找,WildFly提供了如下3种方式:

  • 资源注入,例如@Resource(lookup="...")
  • 标准JNDI API,例如new InitialContext().lookup("...");
  • http-remoting JNDI lookup,例如env.put(Context.PROVIDER_URL, "http-remoting://localhost:8080");

注意,对于第三种方式,由于WildFly不再支持remoting port(4447)等端口,而是只有一个http port(默认8080),所以JNDI命名查找时的URL也从remote://localhost:4447的形式变为http-remoting://localhost:8080。


2) 对于远程JNDI命名查找,在JBoss AS 7(不含)之前,使用jnp查找JNDI命名,但是由于安全性的控制粒度太大而被JBoss AS 7放弃。JBoss AS 7提供了如下2种查找远程JNDI命名的方式:

  • EJB client API,针对无状态EJB的lookup进行了优化
例如:

env.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
(MyRemoteInterface) remoteContext.lookup("ejb:myapp/myejbjar/MyEjbName\!com.test.MyRemoteInterface");
(MyStatefulRemoteInterface) remoteContext.lookup("ejb:myapp/myejbjar/MyStatefulName\!comp.test.MyStatefulRemoteInterface?stateful");

  • jboss-remote-naming(不建议用于EJB)

例如:

                env.put(Context.PROVIDER_URL, "http-remoting://remoteIP:8080");


1 0