在上一篇如何在EJB3中JNDI调用SessionBean(一)文章中我们解决了测试环境中统一调用JNDI的问题,但是当EJB组件开发完成后,正式部署到正式环境中,客户端调用EJB组件怎样去调用呢?现在我们分析这其中出现的问题。

1、 客户端不在同一个JVM环境中,应该怎样处理?
2、 SessionBean对于客户端是隐藏的,开发客户端的程序员怎么能非常方便的获得SessionBean的绑定名?怎么能方便的得到JNDI上下文呢?
3、 各EJB组件分别部署在不同的服务器上,我们怎么能方便的调用?
4、 各EJB组件如果运行在不同的EJB容器中,我们怎么能方便的得到对应的JNDI上下文环境?
针对这些问题,我们逐步的去分析解决。
客户端不在同一个JVM中这是普遍出现的情况,我们可能将web客户端运行在Tomcat上,而EJB运行在JBoss容器中,对于这种情况,我们如果采用上面介绍的第一种情况来获得JNDI上下文就非常不可行,因为EJB的环境的变化会导致太多程序代码的改动,为日后的维护埋下了隐患。所以只能采用第二种方式,将JNDI上下文信息配置在属性文件中,即使以后EJB的环境更换,也可以通过修改配置文件来实现这种改变。
 通过JNDI的方式来调用EJBSessionBean,必然少不了为SessionBean绑定JNDI名。默认的情况下(JBoss),容器会以实现类的类名作为JNDI名。比如getIntialContext().lookup(“LoginBean/remote”); LoginBean就是Login接口的实现类的名字。
@Stateless
@Remote(Login.class)
public class LoginBean implements Login{}
如果这样去做的话,我们开发客户端的程序员就必须要知道这个SessionBean接口的实现类是什么名字,这不是一种好的方式,违背了我们隐藏实现的编程思想。才开始大家建议,约定SessionBean的命名格式为接口+Bean后缀,这是一个比较可行的解决方案。但是一个约定好的命名格式,只能给我们的是一个已知的字符串,我们利用这个字符串所能做的事情太少了。我们利用@Stateless中的name属性,可以为Session Bean起个别名,这个东西应该很好的利用起来。我们再一次讨论,对于客户端来说,什么是透明的呢?无疑是接口,我们能不能把接口的名字作为SessionBean的别名呢。这个主意不错,大家一致通过,看了网上的一些例子,好多人也是采用这种方式。但是也有不好的方面,如果一个SessionBean实现多个接口就不是很好处理了。我们只能再次约定,一个SessionBean只能对应着一个远程接口。这样我们只知道接口就能方便的调用EJB了。
但问题又接踵而至,我们使用EJB作为组件开发技术,很大程度上是利用它强大的分布式计算的能力,这就要求每个EJB组件有可能运行在不同的服务器上,我们调用这些EJB组件,只采用一套上下文配置的方式是非常不可行的。我们需要为每个组件配置各自的JNDI上下文环境。怎么去做呢?在客户端我们为每个组件建立一个Properties文件,里面包含了该组件的JNDI配置。我们调用不同的组件时,我们就去获取该组件的JNDI配置,这已经很好的解决了相关的问题,完全可以适应EJB分布式的环境,但是有没有更好的方法让用户不再去选择每个组件的配置,让他们感觉和本地调用一样简单呢。于是我们在Session Bean接口上做了一些文章,通过自定义annotation的方式,来为每个接口标志相关的组件信息,通过程序解析annotation来获得组件的信息来进行相关的处理。我们定义一个@ComponentInfo的元数据来标注组件的相关信息。
@Target( { TYPE })
@Retention(RetentionPolicy.RUNTIME)
public @interface ComponentInfo {
 String name();
 String description() default "";
}
 name属性为组件的名字,description顾名思义就是组件的描述,通过作用在每个接口上的这个annotation,我们就可以获得组件名称。我们约定客户端的JNDI配置的属性文件的文件名要和这里的组件名称对应,这样我们就可以自动找到该组件需要的JNDI配置。
为了方便EJB组件的开发,我们可以为每个EJB组件做一个全局的接口。将该annotation作用在最上层父类的TYPE上,而该组件所有的SessionBean接口都继承这个接口。
问题都解决了吗?我们不断地寻找问题。
现在问题来了,不同的容器存在自己特有的lookup实现方式,太郁闷了,这样就要将EJB组件和容器绑死了,这为以后EJB组件的移植设置了巨大的障碍。
那么我们该如何解决呢?
请看下一篇:如何在EJB3中JNDI调用SessionBean(三)

posted on 2009-07-20 10:40  LanrenXuan  阅读(1664)  评论(0编辑  收藏  举报