把你编写的软件中那些需要执行制定的任务的类,不放到客户端软件上了,而是给他打成包放到一个服务器上
了。
EJB 是运行在独立服务器上的组件,客户端是通过网络对EJB 对象进行调用的。在Java中,能够实现远程对象
调用的技术是RMI,而EJB 技术基础正是RMI。通过RMI 技术,J2EE将EJB 组件创建为远程对象,客户端就可以通
过网络调用EJB 对象了。
RMI 英文全称是"RemoteMethod Invocation",它的中文名称是"远程方法调用",它就是利用Java 对象序列化
的机制实现分布式计算,实现远程类对象的实例化以及调用的方法。说的更清楚些,就是利用对象序列化来实现远程
调用,也就是上面两个概念的结合体,利用这个方法来调用远程的类的时候,就不需要编写Socket 程序了,也不需
要把对象进行序列化操作,直接调用就行了非常方便。
远程方法调用是一种计算机之间对象互相调用对方函数,启动对方进程的一种机制,使用这种机制,某一台计
算机上的对象在调用另外一台计算机上的方法时,使用的程序语法规则和在本地机上对象间的方法调用的语法规则一
样。
package com.tgb.ejb;
import javax.ejb.Local;
import javax.ejb.Remote;
import javax.ejb.Stateless;
@Remote(value=UserManagerRemote.class)
@Local(value=UserManagerLocal.class)
public class UserManagerBean implements UserManagerLocal,UserManagerRemote {
@Override
public void saveUser(User user) {
System.out.println("Use对象已被保存");
}
}
这种机制给分布计算的系统设计、编程都带来了极大的方便。只要按照RMI 规则设计程序,可以不必再过问在
RMI 之下的网络细节了,如:TCP 和Socket 等等。任意两台计算机之间的通讯完全由RMI 负责。调用远程计算机上
的对象就像本地对象一样方便。RMI 可将完整的对象作为参数和返回值进行传递,而不仅仅是预定义的数据类型。也
就是说,可以将类似Java 哈西表这样的复杂类型作为一个参数进行传递。
如果是较为简单的方法调用,其执行效率也许会比本地执行慢很多,即使和远程Socket机制的简单数据返回的
应用相比,也会慢一些,原因是,其在网络间需要传递的信息不仅仅包含该函数的返回值信息,还会包含该对象序列
化后的字节内容。
会话 Bean 用于实现业务逻辑,它分为有状态 bean 和无状态bean。
package com.foshanshop.ejb3.impl;
import com.foshanshop.ejb3.HelloWorld;
import javax.ejb.Remote;
import javax.ejb.Stateless;
@Stateless
@Remote ({HelloWorld.class})
public class HelloWorldBean implements HelloWorld {
public String SayHello(String name) {
return name +"说:你好!世界,这是我的第一个EJB3哦.";
}
}
在不同方法调用间不保留任何状态 ,事务处理必须在一个方法中结束,通常资源占用较少;可以被共享(因为
它是无状态的) 。无状态Bean不会"专门"保存客户端的状态----(需要强调“专门”是因为无状态会话Bean也会有成
员变量,有成员变量就可以保存状态,但它不会专门为特定的客户端保存状态。)
stateless session bean 创建在对象池中,提供给众多用户使用,如果Bean class 有自己的成员属性(变
量),那么这些变量就会受到所有调用它的用户影响。
package com.foshanshop.ejb3.impl;
import java.util.ArrayList;
import java.util.List;
import javax.ejb.Remote;
import javax.ejb.Stateful;
import com.foshanshop.ejb3.Cart;
@SuppressWarnings("serial")
@Stateful
@Remote(Cart.class)
public class CartBean implements Cart{
private List buyitem = new ArrayList();
public void AddBuyItem(String productName) {
buyitem.add(productName);
}
public List getBuyItem() {
return buyitem;
}
}
对于 StatefulSession Bean,用户每调用一次 lookup()都将创建一个新的 bean 实例,如果你希望一直使用
某个 Bean实例,你必须在客户端缓存存根。
实体bean也叫java bean,实现接口javax.ejb.EntityBean,其描述了特定数据源中的数据,能长时间存在于
EJB Container中,不会随系统的意外中止而消失,并且可以让多个客户同时访问。
实体bean应用实例:
package com.foshanshop.ejb3.bean;
import java.io.Serializable;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.GenerationType;
@SuppressWarnings("serial")
@Entity
@Table(name = "Person")
public class Person implements Serializable{
private Integer personid;
private String name;
private boolean sex;
private Short age;
private Date birthday;
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
public Integer getPersonid() {
return personid;
}
public void setPersonid(Integer personid) {
this.personid = personid;
}
@Column(nullable=false,length=32)
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Column(nullable=false)
public boolean getSex() {
return sex;
}
public void setSex(boolean sex) {
this.sex = sex;
}
@Column(nullable=false)
public Short getAge() {
return age;
}
public void setAge(Short age) {
this.age = age;
}
@ Temporal(value=TemporalType.DATE)
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
}
消息驱动Bean(MDB)是设计用来专门处理基于消息请求的组件。MDB 负责处理消息,而 EJB 容器则负责处理服
务(事务、安全、资源、并发、消息确认,等等),使 bean 开发者把精力集中在处理消息的业务逻辑上。
现在项目对消息驱动bean的应用不多,所以不进行举例说明。