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种标准的命名空间:
除了上述4种标准的命名空间,WildFly还另外提供了如下2种命名空间,他们都在整个服务器范围内有效:
其中可供远程JNDI访问的命名空间是java:jboss的子空间java:jboss/exported。
2. WildFly服务器提供了如下4种发布JNDI命名的方式:
3.JNDI命名的查找
JavaEE应用中查找JNDI命名的方式有多种,具体可以分为在本地(服务器上)查找和在远程(服务器上)查找。
1) 对于本地JNDI命名查找,WildFly提供了如下3种方式:
注意,对于第三种方式,由于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命名的方式:
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");
例如:
env.put(Context.PROVIDER_URL, "http-remoting://remoteIP:8080");