文档章节

通过JNDI访问Jboss中配置的DataSource

j
 javayfs
发布于 2014/10/24 11:07
字数 1991
阅读 745
收藏 0

一直困惑于以下几个问题:

  1. 在客户端通过JNDI获得的究竟是原对象引用,还是序列化之后的另一个对象,或者是像RMI中的stub?

  2. 在本地访问JNDI和远程访问JNDI有什么区别?

  3. web.xml中的resource-ref元素到底有什么用,并且应该如何使用?

 

花了一些时间,做了一些试验,得了一些结果,消了一些困惑,当然还写了一些博客。本文将以Jboss 5和MySQL为例,先在Jboss 5 中配置好MySQL的DataSource,再通过远程调试方式启动Jboss,另外写了一个很小的web程序和一个独立的main函数来查看 DataSource的可访问性。本文假设在Jboss中配置MySQL DataSource的jndi-name=MySqlDs。

 

以调试模式启动Jboss时,需要将 ${Jboss 根目录}/bin/run.sh文件中加入以下调试参数:

 

JAVA_OPTS="-Xdebug -Xrunjdwp:transport=dt_socket,address=8787,server=y,suspend=n $JAVA_OPTS"

 

此时,Jboss的调试监听端口为8787,在IDE中(比如IntelliJ IDEA或Eclipse)中,开启调试,并将监听端口也设成8787,此后便可以调试你的应用程序了。

 

(一)在服务器外部(另一个JVM)中访问DataSource

笔者已经在另一篇博客中谈到了在服务器外部访问DataSource的情况,这里再做一个小结:在服务器外部是可以访问DataSource的,但是在Jboss中配置MySQL时,需要在mysql-ds.xml文件中加入:

 

   <use-java-context>false</use-java-context>


这样告诉Jboss,将DataSource绑定在Global名字空间,表示该资源可以被服务器外部所访问。如果use-java- context=true,那么表示DataSource被绑定在了java:名字空间,此时的DataSource只能被服务器内部访问,即部署在 Jboss中的web应用才可以访问。

 

笔者写了一个独立于服务器的小程序,通过JNDI访问到Jboss中的DataSource,通过调试,发现通过context.lookup("MySqlDs")所获得的对象事实上并不是一个DataSource对象,而是一个JRMPInvokerProxy对象,该对象实现了Serializable接口,所以从远程访问JNDI时,返回的是一个序列化之后的JRMPInvokerProxy对象,而不是DataSource对象本身。另外,JRMP为Java Remote Method Protocol(Java远程方法协议)的简称,主要用于查找和引用远程对象,比如RMI便工作于JRMP的上层。而通过 JRMPInvokerProxy的名字可以看出,客户端实际上使用了Java的动态代理来完成对DataSource的访问。

 

(二)在服务器内部访问DataSource

在服务器内部,可以通过两种方式访问DataSource,一种和外部访问时一样,给出DataSource在JNDI中的原配置名称 (MySqlDs)即可;另一种也是通过JNDI的方式,但是通过额外地配置web.xml文件和jboss-web.xml文件来完成,这样只是多加了 一个新的逻辑层,当然访问DataSource的代码也略有差别。

 

(1)在服务器内部直接访问DataSource

在(一)中我们讲到,如果要在服务器外部访问DataSource,需要将DataSource绑定在Global空间下。在服务器内部是没有这样 的限制的,我们既可以将use-java-context设置成false(Global名字空间),也可以将其设置成true(java:名字空间), 只是他们的JNDI全名称不一样。对于配置在Global名字空间中的DataSource,访问时和服务器外部访问一样,直接用jndi-name就行 了:context.lookup("MySqlDs")。而当DataSource被配置在java:名字空间中时,我们则需要额外加上java:前 缀,即context.lookup("java:/MySqlDs")。

 

除了上面的不同外,配置在Global名字空间和配置在java:名字空间的DataSource访问原理也不一样。当把DataSource配置在Global名字空间时,通过lookup获得的DataSource实际上为一个WrapperDataSource对象,WrapperDataSource类实现了Referenceable接口。通过该接口,WrapperDataSource对象维持了一个到真正DataSource的引用,关于此更多的资料请参考这个网页

 

当把DataSource配置到java:名字空间时,虽然通过lookup获得的DataSource也是一个 WrapperDataSource对象,但是它并不维持到任何对象的引用,此时WrapperDataSource对象可以说就是配置的 DataDource本身。原因很简单,既然是在同一个JVM中访问,既然java:名字空间中的JNDI资源本来就是用于服务器内如使用的,那直接指向 配置的DataSource对象不就行了。

 

(2)通过配置web.xml和jboss-web.xml访问DataSource

上文中我们在调用lookup方法时,直接使用了DataSource的JNDI名称。这种方式不好的地方在于:如果之后我们需要修改 DataSource的名字,比如我们需要从MySQL迁移到Ocracl,那么DataSource的名称自然应该从MySqlDs改为 OrcacleDs,此时我们就需要在程序中修改DataSource的名字,然后重新部署程序。为了解决这个问题,我们可以在中间引入一个逻辑层,通过 该逻辑层,我们不需要修改程序,只需要修改web.xml和jboss-web.xml(在其它服务器中应该也有相应配置文件,比如GlassFish中 的sun-web.xml),此时服务器会自动监视到这些配置文件的修改,然后做相应的配置变化处理。这样,我们便省去了重新部署应用程序的必要。另外, 通过引入这个逻辑层,我们也可将程序的开发和部署分离开。

 

通过配置web.xml和 jboss-web.xml访问DataSource的基本原理为:现在jboss-web.xml中为DataSource指定一个逻辑名称,再在 web.xml文件中引入该逻辑名称,以使该逻辑名称对应用程序可见。这样在程序中调用lookup方法时,只需要使用这个逻辑名称即可。

 

具体方法如下:

先配置jboss-web.xml文件,和web.xml文件一样,该文件应该位于WEB-INF目录下。

<?xml version="1.0" encoding="UTF-8"?>

<jboss-web>

<resource-ref>

  <res-ref-name>MySqlDS-WhateverName</res-ref-name>

  <res-type>javax.sql.DataSource</res-type>

  <jndi-name>java:/MySqlDS</jndi-name>

</resource-ref>

</jboss-web>

 

以上配置中,res-ref-name即为DataSource的逻辑名,我们可以任意给定。jndi-name为DataSource在mysql-ds.xml中配置时的JNDI名称。

 

再配置web.xml文件,在web.xml文件中加入以下配置:

<resource-ref>

  <description>MySQL Connection</description>

  <res-ref-name>MySqlDS-WhateverName</res-ref-name>

  <res-type>javax.sql.DataSource</res-type>

  <res-auth>Container</res-auth>

</resource-ref>

 

这里需要注意的是,web.xml文件中的res-ref-name应该和jboss.xml文件中的res-ref-name保持一致。

 

根据Java EE标准,服务器会为每个组件(比如某个Servlet,某个EJB等)创建一个属于它自己的Environment Naming Context (ENC),这个ENV本身也被放在服务器JNDI资源中。然后将该组件使用的JNDI资源放在这个ENC下。通过上面对web.xml和jboss- web.xml的配置,我们实际上是将DataSource资源放在Servlet容器组件中,即将DataSource的逻辑名放在了Servlet的 ENV中,并对每个Servlet组件可见。这样在程序中访问DataSource时,我们不仅可以通过直接访问DataSource在配置时的JNDI 名,还可以先获得ENV,再从ENV中访问DataSource,代码如下:

 

Context envContext  = (Context)ctx.lookup("java:/comp/env");

DataSource dataSource = (DataSource)envContext.lookup("MySqlDS-WhateverName");

 

以上程序中,先获得ENV,ENV的JNDI名字始终为java:/comp/env,比如在Servlet中调用 ctx.lookup("java:/comp/env")时,获得的是该Servlet的ENV,如果在EJB中调用相同的 ctx.lookup("java:/comp/env"),则获得了该EJB组件的ENV,关于ENV的更多信息,请参考此文档

获得ENV之后,我们便可以访问DataSource了,请注意,此时我们只需要给出DataSource在web.xml中配置的逻辑名(res-ref-name)即可,使用其它的名字,比如MySqlDs和java:/MySQLDs,反而会出错。

 

(三)总结

 

对于服务器外部访问DataSource,请参考表1:


对于在服务器内部访问DataSource,请参考表2:


在服务器内部通过配置web.xml和jboss-web.xml方式访问DataSource,请参考表3:


本文转载自:http://www.davenkin.me/post/2012-10-20/40039814527

j
粉丝 4
博文 12
码字总数 11740
作品 0
广州
程序员
私信 提问
加载中

评论(0)

JBoss4.2.2.GA下部署OpenJWeb介绍

JBoss环境下部署OpenJWeb的过程 时间:2011-10-20 来源:www.openjweb.com 作者:abao 内容字号:小|大 JBOSS4.2.2GA环境下部署OpenJWeb的步骤 配置JAVA_OPTS参数 这一步骤很重要,因为需要指...

迷途d书童
2012/03/09
620
0
EJB数据源的配置(以JBoss为例)

数据库持久化是建立在JDBC标准之上的一个规范。 JBoss数据源的配置: 1. 找到数据源配置的模板,在JBoss的安装目录里面有 在这个目录下面以-ds.xml结尾的文件就是模板文件。 以oracle为例,下...

长平狐
2013/12/25
475
0
JBoss Data Grid 6.1 发布,分布式 K/V 存储网格

JBoss Data Grid 6.1 发布了,红帽JBoss Data Grid 6是一个内存、键值型的数据存储解决方案,基于JBoss社区项目Infinispan构建,包含了JBoss企业应用平台和运营网络的部分组件。无论 Java程序...

红薯
2013/04/10
1K
0
【转】Jboss 4.2.3 集群配置方法

一、准备工作 安装JDK 1.5或以上版本,Jboss 4.2.3,apache 2.2.x, mod_jk.so 配置JAVAHOME, JBOSSHOME,APACHE_HOME环境变量 其中 mod_jk是apache服务器连接Jboss的插件 二、配置 假设有两台...

mj4738
2012/02/10
456
0
2010(初次接触EJB 小节)

初次体验了下EJB的开发 今天整理了下 企业中就我自己公司里面对于EJB的使用做一次切身的体会 配置数据源,因为Ejb工程 是要部署到jboss的 所以在jboss里面配置数据源和tomcat里面多少有些出入...

Zofda
2012/02/28
82
0

没有更多内容

加载失败,请刷新页面

加载更多

java关键字 —— new、this、static

  java关键字,也叫保留字(50个),是java有特殊意义的标识符,不能用作参数名、变量名、方法名、类名、包名等。   现在我们讲讲其中三个关键字的使用吧~~~ 一、new关键字 1. 用途:新建...

osc_s2b5kacl
29分钟前
21
0
java 集合框架的工具类Collections

sort(),max(),binarySearch(),fill() public class CollectionsDemo { public static void main(String[] args) { replaceAllDemo(); } public static void replaceAll......

osc_r9yyhhqz
30分钟前
25
0
创龙基于Xilinx Kintex-7系列高性价比FPGA开发板散热风扇接口、SATA接口

处理器 Xilinx Kintex-7系列FPGA处理器,芯片型号为XC7K325T-2FFG676I,兼容XC7K160T/410T-2FFG676I,高达326K逻辑单元,840个DSP Slice,硬件如下图: 散热风扇接口 开发板引出1个散热风扇接...

Tronlong创龙
31分钟前
27
0
【经验分享】学习Java的好书有哪些?Java书籍清单

Java书籍是程序员学习提升技能的重要学习渠道,通过书籍Java程序员可以学习当前流行、重要的相关技能。经典的书经受时间的考验,随着岁月的流逝变得越来越重要,让我们不断的学习和进步。 为...

osc_b1kaj6np
31分钟前
22
0
java Collections的reverseOrder(),SynList()

Collections的reverseOrder(比较器)返回相反的比较器,可以逆转比较器。 SynList()可以让非同步变成同步,底层实现synchronized(){}。 swap交换元素位置。 Collections.shuffle()随机重新排序...

osc_2gkfj43j
32分钟前
27
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部