一、EJB的简介
1、什么是EJB
EJB是Enterprise JavaBean的简称,是Java企业Bean的意思,是Java的核心代码,是一个用于分布式业务应用的标准服务器端组件模式,主要包括会话Bean(Session Bean),实体Bean(Entity Bean)和消息驱动Bean(MessageDriven Bean)三种,下面对这些Bean做详细的解释。
2、EJB的运行环境
EJB需要运行在EJB容器,每个Java EE应用服务器都含有EJB容器和Web容器,所以既可以运行EJB,也可以运行Web应用。目前支持EJB 3.0的应用服务器有JBoss,WebLogic等。
二、会话Bean(Session Bean)
1、什么是会话Bean
Session Bean用于实现业务逻辑。比如:要实现两个数的相加或是从数据库中读取数据,都是通过Session Bean来实现的。Session Bean相当于我们熟悉的Action类。
Session Bean分为两种:有状态Bean(Stateful Session Beans)和无状态Bean(Stateless Session Beans)。
要开发一个Session Bean,需要定义接口和bean class。其中接口分为远程(Remote)和本地(Local)接口。
远程接口(Remote interface):定义了Session Bean的业务方法,这些方法可以被来自EJB容器之外的应用访问到。
本地接口(Local interface):同样定义了Session Bean的业务方法,这些方法可以同处于EJB容器内的其他应用使用。因为local接口允许Bean之间直接通过内存交互,没有分布式对象协议的开销,从而改善了性能。
Bean类(bean class):Bean class包含了业务逻辑,它必须具备一个远程或本地接口。
2、无状态Bean(Stateless Session Beans)
(1)无状态Bean不维护会话状态,意味着一个Bean实例可以为多个用户服务。简单的说,就是当无状态会话Bean部署到应用服务器时,EJB容器会为它预先创建一些Bean实例放在对象池。当有用户访问EJB方法时,EJB容器会从对象池中取出一个实例为之服务,服务完成后就回到对象池。当下一个用户再访问EJB方法时,EJB容器有可能再次把该实例取出来为之服务。正因为如此,无状态会话Bean只需要少量的实例就可以为成千上万个用户服务,大大提高了系统性能。
(2)无状态Bean比有状态Bean更具性能优势,条件允许的情况下开发人员应该首先考虑使用无状态会话Bean。
(3)无状态Bean定义实例如下:
远程接口(Remote interface)如下:
@Remote
public interface MyFirstDAO extends DAO{
}
本地接口(Local interface)如下:
@Local
public interface MyDoubleDAO extends MyFirstDAO {
}
无状态Bean定义如下:
@Stateless(mappedName="MyFirstDAO ")
@Remote (MyFirstDAO .class)
@Local(MyDoubleDAO .class)
public class MyFirstDAOBean extends DaoSupport implements MyFirstDAO , MyDoubleDAO{
}
3、 Stateful Session Bean(有状态Bean)
(1)Stateless Session Bean创建在对象池中,提供给众多用户使用,如果Bean class有自己的成员属性(变量),那么这些变量就会受到所有调用它的用户的影响。在一些应用场合中,有时需要每个用户都有自己的一个实例,这个实例不受其他用户的影响。就好比购物车对象,每个用户都应有自己的购物车,谁都不希望有人往自己的购物车里添加或拿掉商品,而有状态Bean正好满足满足了这种需求。每个有状态的Bean在Bean实例的生命周期内都只服务一个用户,Bean class的成员变量可以在不同的方法调用间维护特定于某个用户的数据。正因为在Bean实例的生命周期内Stateful Session Bean保持了用户的信息,所以叫有状态的Bean。
(2)Stateful Session Bean必须实现Serializable接口,这样EJB容器才能在它们不再使用时,把它们序列化保存到硬盘上。
(3)有状态Bean定义实例如下:
业务接口:Cart.java
import java.io.Serializable;
import java.util.List;
public interface Cart extends Serializable {
public void AddBuyItem(String productName);
public List<String> getBuyItem();
}
Bean类:
import java.util.ArrayList;
import java.util.List;
import javax.ejb.Remote;
import javax.ejb.Stateful;
import com.yuyu.ejb3.Cart;
@SuppressWarnings("serial")
@Stateful
@Remote(Cart.class)
public class CartBean implements Cart{
private List<String> buyitem = new ArrayList<String>();
public void AddBuyItem(String productName) {
buyitem.add(productName);
}
public List<String> getBuyItem() {
return buyitem;
}
}
三、实体Bean(Entity Bean)
1、什么是实体Bean
创建实体Bean的目的为了实现持久化,EJB3.0遵循的持久化规范是Java Persistence API,即JPA。JPA定义了一种方法,可以将常规的Java对象映射到数据库。这些普通的Java对象被叫做Entity Bean。其实除了用JPA元数据将其映射到数据库外,Entity Bean与其他Java类没有任何区别。就是我们熟悉的POJO。
2、Entity Bean介绍
(1)Entity Bean必须用@ Entity注明。
(2)Entity Bean必须用@id唯一标示主键。
(3)如果实体Bean对象需要返回客户端,必须实现 Serializable接口。
(4)通过在Entity Bean中加注释可以表示表和表的关联,例如:一对多要用@OneToMany来表示。
(5)JPA还提供了好多注解来实现别的功能。
3、Entity 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;
}
}
4、 实体Bean的管理器EntityManaager
EntityManaager可以用来添加、删除、更新实体Bean,通过主键查找实体Bean。
EntityManaager管理实体Bean的实例如下:
import java.util.List;
import javax.ejb.Remote;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import com.foshanshop.ejb3.PersonDAO;
import com.foshanshop.ejb3.bean.Person;
@Stateless
@Remote (PersonDAO.class)
public class PersonDAOBean implements PersonDAO {
@PersistenceContext
protected EntityManager em;
public void insertPerson(Person person) {
em.persist(person);
}
public Person getPersonByID(int personid) {
return em.find(Person.class, personid);
}
public void mergePerson(Person person) {
em.merge(person);
}
@SuppressWarnings("unchecked")//关闭unchecked警告
public List<Person> getPersonList() {
Query query = em.createQuery("select o from Person o order by o.personid asc");
return (List<Person>) query.getResultList();
}
public void deletePerson(int personid) {
Person person = em.find(Person.class, personid);
if(person!=null) em.remove(person);
}
public void updateName(String newname, int personid) {
Person person = em.find(Person.class, personid);
if(person!=null) person.setName(newname);
}
}
四、消息驱动Bean(MessageDriven Bean)
消息驱动Bean(MDB) 是设计用来专门处理基于消息请求的组件;
1、java消息服务(JMS)
用于访问企业消息系统开发的中立API,企业消息系统可以协助应用软件通过网络进行消息交互
JMS编程原理:应用程序1-->消息-->Jboss JMS-->消息-->应用程序2
2、JMS中的消息
一条Message由头(head)、属性(property)、主体(body)组成
有这些来自Message接口的消息类型:StreamMessage、MapMessage、TextMessage、ObjectMessage、ByteMessage
3、消息的传递模型
点对点(point-to-point) 一条消息只能传递给一个接受方,用javax.jms.Queue表示
发布/订阅(publish/subscribe) 一条消息能传递传递给多个接受方,用javax.jms.Topic表示
两种类型都是基于公共基类javax.jms.Destination类
4、采用消息驱动Bean接受消息MDB
@MessageDriven(activationConfig={
@ActivationConfigProperty(propertyName="destinationType",propertyValue="javax.jms.Queue"),
@ActivationConfigProperty(propertyName="destination",propertyValue="queue/xinrongsoft"),
})
public class QueueDriverBean implements MessageListener{
@Override
public void onMessage(Message message) {
TextMessage textMessage=(TextMessage) message;
System.out.println(textMessage);
}
}