[原创]EJB初试_Tomcat, WebLogic及J2EE讨论区_Weblogic技术|Tuxedo技术|中间件技术|Oracle论坛|JAVA论坛|Linux/Unix技术|hadoop论坛_联动北方技术论坛  
网站首页 | 关于我们 | 服务中心 | 经验交流 | 公司荣誉 | 成功案例 | 合作伙伴 | 联系我们 |
联动北方-国内领先的云技术服务提供商
»  游客             当前位置:  论坛首页 »  自由讨论区 »  Tomcat, WebLogic及J2EE讨论区 »
总帖数
1
每页帖数
101/1页1
返回列表
0
发起投票  发起投票 发新帖子
查看: 2367 | 回复: 0   主题: [原创]EJB初试        下一篇 
lijun.fang
注册用户
等级:上尉
经验:751
发帖:29
精华:0
注册:1970-1-1
状态:离线
发送短消息息给lijun.fang 加好友    发送短消息息给lijun.fang 发消息
发表于: IP:您无权察看 2015-3-29 18:14:49 | [全部帖] [楼主帖] 楼主

EJB是一个用于分布式业务应用的标准服务端组件模型。采用EJB架构编写的应用是可伸缩的、事务性的、多用户安全的。采用EJB编写的这些应用,可以部署在任何支持Enterprice JavaBeans规范的服务器平台,如jbossweblogic等。

EJB实际上是用于编写业务层代码。EJB提供了很多在企业开发中需要使用到的服务,如事务管理/安全/持久化/分布式等,因为这些服务由EJB容器提供,无需我们自行开发,这样大大减少了我们的开发工作量. EJB是程序实现了很大程度上的解耦

因为EJB设计的初衷是用于分布式场合,如果你的程序不需要使用到分布式能力的话,就没有必要使用EJB,使用spring+hibernate就可以很轻松的实现一个服务。

EJB比较适合用于大型企业,因为大型企业一般都会存在多个信息系统,而这些信息系统又相互关联。为了避免业务功能重复开发,实现最大程度的重用,有必要把业务层独立出来,让多个信息系统共享一个业务中心,这样应用就需要具备分布式能力。

如下图

北京联动北方科技有限公司

分布式应用的一个比较典型的应用就是当前比较火的网上商城:

北京联动北方科技有限公司

注意:tomcat只是一个web容器而不是应用服务器,tomcat没有实现ejb规范。

应用服务器组件结构如下:

北京联动北方科技有限公司

EJB3的运行环境(以Weblogic为例)


是商业市场占有率第一的商业JavaEE应用服务器,它具有出色的稳定性,并提供了人性化的管理界面,还有企业需要使用到的众多功能。

EJB中的三种bean

1.会话bean(session bean)

负责与客户端交互,是编写业务逻辑的地方,在会话bean中可以通过jdbc直接操作数据库,但大多数情况下都是通过实体bean来完成对数据库的操作.

2.实体bean(entity bean)

它实际上属于java持久化规范(简称JPA)里的技术, JPA的出现主要是为了简化现有的持久化开发工作和整合ORM技术,结束现在HibernateTopLinkORM框架各自为营的局面。

3.消息驱动bean(message-driven bean)

它是专门用于异步处理java消息的组件.具有处理大量并发消息的能力.

回话bean(包括有状态和无状态)

无状态会话bean

平常,我们使用最多的是无状态bean,因为它的bean实例可供多个用户使用,所以它的性能比有状态bean.正因为一个bean实例被多个用户使用.那么,前一个用户设置的值有可能被后一个用户所修改,所以它无法正确保存某个用户设置的值,因此是无状态的.

有状态会话bean

有状态bean平常使用的并不多,因为它的一个bean实例只供一个用户使用,所以性能开销比较大,正因为它的实例只被一个用户使用, 用户为它设置的值是不会被其他用户修改,所以可以正确保存用户设置的值,因此是有状态的.

关于这两个的理解,个人觉得是,无状态会话bean就类似于一个servlet,是单例模式的,可以被多个用户并发的访问,而有状态会话bean就类似于一个strut2,是原型的,针对每一个用户的访问,都有一个与之对应的strut2的实例。

示例代码:

(开发一个无状态的回话bean


步奏:

1.编写一个接口(接口可以是远程接口或本地接口)

2.写一个实现类

3.打成jar包,部署到weblogic服务器里面

相关代码:

接口:

package com.langdingbj.sessionbean;
/**font-family:"Courier New";mso-font-kerning:0pt">

 * 定义一个接口

 * @authorJUN

 */0pt">
publicinterface HelloEJB {0pt">
      void show(String msg);
}


实现类:

package com.langdingbj.sessionbean.impl;
import javax.ejb.Remote;
import javax.ejb.Stateless;
import com.langdingbj.sessionbean.HelloEJB;
/**

 * 第一个无状态的回话bean

 * @author JUN

 */
@Stateless
@Remote(HelloEJB.class)
public class HelloEJBImpl implements HelloEJB {
       public void show(String msg) {
             System.out.println("你好!.." + msg);
       }
}


部署即运行方法见:

http://bbs.landingbj.com/showtopic.jsp?boardcode=WLTL&hit=510&showid=245534&rootid=245534


注意:本地接口和远程接口的区别

如果是本地接口:

修改如下(默认是本地接口,可以不写即为默认):

@Statelessfont-family:"Courier New";mso-font-kerning:0pt">
@Local(HelloEJB.class)0pt">
publicclass HelloEJBImpl implements HelloEJB {0pt">
      publicvoid show(String msg) {0pt">
            System.out.println("你好!.." + msg);
      }
}


如果是有状态的bean,写法如下:

@Stateful0pt">
@Local(HelloEJB.class)0pt">
publicclass HelloEJBImpl implements HelloEJB {0pt">
      publicvoid show(String msg) {0pt">
            System.out.println("你好!.." + msg);
      }0pt">
}


ejb和应用程序是使用的同一个jvm的时候,就是用本地接口,不是同一个jvm的时候就是用远程接口,而在实际开发中由于不知道到底是不是在一个jvm里面运行,所以这两种情况都要考虑,为了避免在运行出错建议写法如下:

北京联动北方科技有限公司

接口部分:

package com.langdingbj.sessionbean;
/**font-family:"Courier New";mso-font-kerning:0pt">

 * 定义一个接口

 * @authorJUN

 */0pt">
publicinterface HelloEJB {0pt">
      void show(String msg);0pt">
}


新增部分:

package com.langdingbj.sessionbean;
/**font-family:"Courier New";mso-font-kerning:0pt">

 * 定义一个接口

 * @authorJUN

 */0pt">
publicinterface HelloEJBLocal extends HelloEJB{font-family:"Courier New";mso-font-kerning:0pt">
}


实现部分:

package com.langdingbj.sessionbean.impl;
import javax.ejb.Local;
import javax.ejb.Remote;
import javax.ejb.Stateful;
import com.langdingbj.sessionbean.HelloEJB;
import com.langdingbj.sessionbean.HelloEJBLocal;
/**

 * 第一个无状态的回话bean

 * @author JUN

 */
@Stateful
@Remote(HelloEJB.class)
@Local(HelloEJB.class)
public class HelloEJBImpl implements HelloEJBLocal {
       public void show(String msg) {
             System.out.println("你好!.." + msg);
       }
}


实体bean

它有一个主健作为唯一的标识符

组成部分: 由本地接口、远程接口、bean类、主健类和配置描述器组成。

本地接口:扩展了javax.ejb.ejbhome接口,包括create()、remove()、finder home等方法

具体含义如下:

    1)create()方法调用bean类中的ejbcreate()方法。相当于数据的insert 方法。

    2)remove()方法相当于数据库的delete                                                                         3)finder()方法,使客户能够查询和接收满足查询条件的实体bean的引用。每个实体bean的本地接口中都必须有一个findbyprimarykey() 方法

4)home 方法,类似于无状态会话bean

②主健类:实体bean必须包括一个主健类,主健类用于标识实体bean实例,而且实体bean数据类型必须是唯一的。主健类可以是java的基本类型string integer 也可以是用户自定义的。也可以是多个字段的主健的复合主健。

 bean 类和bean的上下文环境:

实现javax.ejb.ejbobject 接口,其中包含业务方法的语法格式定义.

                 bean 类实现了javax.ejb.entitybean接口,javax.ejb.sessionbean接口一样,entitybean 接口包含了ejb

容器调用bean实例的语法格式.

bean的构造器执行之后,立即调用setentitycontext() 方法,同时把bean实例的entitycontext 传递给它.bean类实现了home方法和远程接口中的业务方法,home方法是针对匿名实例的方法不应使用有关的主健值.


分为:

    1)、容器管理持久性(containermanagerd persistencecmp

特点: ejb 容器自动生成,用于把实体bean的数据写入到数据库中。

优点: bean作者可以避免编写实体bean与关系数据库数据访问方面的代码。cmp将自动处理这一过程。

个性每一个cmp 实体bean 都有一组容器管理的字段,这些字段存储在数据库,并可从中加载.通常,每个容器管理的字段都对应于关系数据库中的一个列.容器管理的每个字段必须在ejb-jar.xml中定义,这使容器能够把容器管理的字段与bean类中的setget方法进行匹配比较.另外,bean作者可以增加另外一个cmp配置描述文件 weblogic-cmp-rdbms.xml,其中包含数据库表名和每个容器管理的字段和相应的数据列的映射.

    2)bean管理持久性(beanmanagerd persistence bmp

特点:bmp实体中,bean作者需要自己编写数据库访问代码,也就是编写jdbc代码,插入、删除和查询数据库中的实体bean数据。

优点:可以让bean的作者完全灵活的处理实体bean的持久性数据,因为作者需要写数据访问的代码,他几乎可以使用任何持久性存储方式ejb2.0 cmp提供实体bean之间的标准关系映射,使容器能自动管理业务对象之间的交互。cmp拥有更多的访问控制,因此cmpbmp有较好的性能。


消息驱动bean


首先介绍一下Java消息服务(Java Message Service),Java 消息服务(Java Message Service,简称JMS)是用于访问企业消息系统的开发商中立的API。企业消息系统可以协助应用软件通过网络进行消息交互。JMS的编程过程很简单,概括为:应用程序A发送一条消息到消息服务器的某个目得地(Destination),然后消息服务器把消息转发给应用程序B。因为应用程序A和应用程序B没有直接的代码关连,所以两者实现了解偶。如下图:

北京联动北方科技有限公司

消息的类型(他们都是派生自Message 接口):

1.StreamMessage:一种主体中包含Java 基元值流的消息。

2.MapMessage:一种主体中包含一组名-值对的消息。没有定义条目顺序。

3.TextMessage:一种主体中包含Java 字符串的消息(例如,XML 消息)。

4.ObjectMessage:一种主体中包含序列化Java 对象的消息。

5.BytesMessage:一种主体中包含连续字节流的消息。

消息的传递模型

JMS 支持两种消息传递模型:点对点(point-to-point,简称PTP)和发布/订阅(publish/subscribe,简称pub/sub)。这两种消息传递模型非常相似,但有以下区别:

PTP 消息传递模型规定了一条消息只能传递给一个接收方。采用javax.jms.Queue 表示。

Pub/sub 消息传递模型允许一条消息传递给多个接收方。采用javax.jms.Topic表示

javax.jms.Queue javax.jms.Topic 都扩展自javax.jms.Destination 类。

开始JMS编程前,我们需要先配置消息到达的目标地址(Destination),因为只有目标地址存在了,我们才能发送消息到这个地址。

java类中发送消息,

一般发送消息有以下步骤:

(1) 得到一个JNDI初始化上下文(Context)

         InitialContext ctx = new InitialContext();


(2) 根据上下文查找一个连接工厂 QueueConnectionFactory 。该连接工厂是由JMS提供的,不需我们自己创建,每个厂商都为它绑定了一个全局JNDI,我们通过它的全局JNDI便可获取它;

         QueueConnectionFactory factory = (QueueConnectionFactory) ctx.lookup("QueueConnectionFactory");


(3) 从连接工厂得到一个连接 QueueConnection

         conn = factory.createQueueConnection();


(4) 通过连接来建立一个会话(Session);

         session = conn.createQueueSession(false, QueueSession.AUTO_ACKNOWLEDGE);


这句代码意思是:建立不需要事务的并且能自动确认消息已接收的会话。

(5) 查找目标地址:

例子对应代码:Destination destination = (Destination ) ctx.lookup("queue/msg");

(6) 根据会话以及目标地址来建立消息生产者MessageProducer QueueSenderTopicPublisher都扩展自MessageProducer接口)

例子对应代码:

MessageProducer producer = session.createProducer(destination);
TextMessage msg = session.createTextMessage("您好,这是我的第一个消息驱动Bean");
producer.send(msg);


采用消息驱动Bean (Message Driven Bean)接收消息

消息驱动Bean(MDB)是设计用来专门处理基于消息请求的组件。它和无状态Session Bean一样也使用了实例池技术,容器可以使用一定数量的bean实例并发处理成百上千个JMS消息。正因为MDB具有处理大量并发消息的能力,所以非常适合应用在一些消息网关产品。如果一个业务执行的时间很长,而执行结果无需实时向用户反馈时,也很适合使用MDB。如订单成功后给用户发送一封电子邮件或发送一条短信等。

一个MDB通常要实现MessageListener接口,该接口定义了onMessage()方法。Bean通过它来处理收到的JMS消息。

package javax.jms;
public interface MessageListener {
       public void onMessage(Message message);
}


当容器检测到bean守候的目标地址有消息到达时,容器调用onMessage()方法,将消息作为参数传入MDBMDBonMessage()中决定如何处理该消息。你可以使用注释指定MDB监听哪一个目标地址(Destination)。当MDB部署时,容器将读取其中的配置信息。

详细配置如下:

@MessageDriven(activationConfig =
{
       @ActivationConfigProperty(propertyName="destinationType",
       propertyValue="javax.jms.Queue"),
       @ActivationConfigProperty(propertyName="destination",
       propertyValue="queue/msg")
})
public class PrintBean implements MessageListener {
       public void onMessage(Message msg) {
            //处理代码
      }
}




赞(0)    操作        顶端 
总帖数
1
每页帖数
101/1页1
返回列表
发新帖子
请输入验证码: 点击刷新验证码
您需要登录后才可以回帖 登录 | 注册
技术讨论