zoukankan      html  css  js  c++  java
  • EJB2.1学习系列二:session beans

    Session Object

    会话bean对象有如下特征:

    • 为某单个客户端调用
    • 具有事务性
    • 在基础数据库中更新共享数据
    • 生命周期相当较短
    • 当EJB容器宕掉时,会被移除掉,客户端需要重新建立一个新的session对象

    session beans 又分为stateful(有状态) beans和stateless(无状态) beans,它们的api区别很小。

    在客户端来看,一个session object是运行在服务器上的实现了一些业务逻辑的对象。客房端通过session beans定义的组件接口调用session object,通过JNDI(java naming and directory)定位一个session bean的home interface,如下:

    1 InitialContext context= new InitialContext(env);
    2 Object obj=context.lookup("FirstEjb");
    3 HelloWorldHome home=(HelloWorldHome)PortableRemoteObject.narrow(obj,HelloWorldHome.class);

    对于session beans发布在本地的情况,即非remote session beans,用如下调用代码:

    1 InitialContext context= new InitialContext();
    2 HelloWorldHome home=(HelloWorldHome)context.lookup("java:comp/env/ejb/FirstEjb");

    一个Ejb容器给客户端提供的服务如下图:


    Session Bean’s Remote Home Interface

    对于部署在ejb容器中的每个session bean所对应的remote home interface,容器会实现这个接口,并且会让客户端通过JNDI查找到该home interface的实现对象。

    remote home interface允许客户端做如下事:

    • 创建一个session object
    • 移除一个session object
    • 得到session bean的javax.ejb.EJBMetaData接口,这样可以让客户端得到session object的相关元数据信息,为实现服务端/客户端低耦合提供可能

    创建一个session object

    一个home interface可以定义多个create***的方法来创建session object对象,这个方法的参数则可以用来初始化session object的状态。如下:

    public interface CartHome extends javax.ejb.EJBHome {
    Cart create(String customerName, String account) throws RemoteException,
    BadAccountException, CreateException;

    Cart createLargeCart(String customerName, String account)
    throws RemoteException, BadAccountException, CreateException;
    }

    客户端则可以如下调用:

    cartHome.create(“John”, “7506”);


    EJBObject and EJBLocalObject

    客户端从来不会直接访问session bean的实现例化对象,对是通过定义的组件接口去调用,而这个接口的实现类则是由ejb容器提供实现。

    session ojbect的生命周期

    一个session object直到home interface调用create***方法后才会存在并被客户端引用。

    一个简单session bean的示例代码

    首先,我们脑海里载入平时用spring做开发时的思维方式,一般是先定义核心业务接口,然后写一个具体的接口实现类。

    package jcli.cnblogs.ejb;

    import java.rmi.RemoteException;

    import javax.ejb.EJBObject;

    public interface HelloWorldService extends EJBObject{

    public String getHello() throws RemoteException;

    }

    HelloWorldService是我们的业务接口,里面有个getHello的方法。只不过这里的业务接口要继承EJBObject接口。

    然后我们要写一个实现类

    package jcli.cnblogs.ejb;

    import java.rmi.RemoteException;

    import javax.ejb.EJBException;
    import javax.ejb.SessionBean;
    import javax.ejb.SessionContext;

    public class HelloWorldServiceImpl implements SessionBean{

    private HelloWorldVo helloWorldVo;

    /**
    *
    */
    private static final long serialVersionUID = -3082113467604080824L;

    public String getHello() throws EJBException, RemoteException {
    System.out.println("server execute getHello method");
    if(helloWorldVo == null){

    return "create a empty vo....";
    }else{
    return "create a vo : " + this.helloWorldVo.getId() + " , " + this.helloWorldVo.getName();
    }
    }

    public void ejbCreate() throws javax.ejb.CreateException {
    System.out.println("ejbCreate....");
    };

    public void ejbCreateState(Integer id,String name) throws javax.ejb.CreateException {
    System.out.println("ejbCreate....");
    helloWorldVo = new HelloWorldVo();
    helloWorldVo.setId(id);
    helloWorldVo.setName(name);

    };

    @Override
    public void ejbActivate() throws EJBException, RemoteException {
    System.out.println("ejbActivate....");

    }

    //下面省略SessionBean接口其它实现方法
    }

    大家注意这里的实现类并没有显示实现HelloWorldService接口,而是实现了SessionBean接口,但是里面必需要有HelloWorldService接口里的所有方法(getHello方法),其它的方法先不用关注,后面会讲到。

    接下来,作为远程客户端调用,我们还需要一个home interface去创建remote object对象。如下:

    package jcli.cnblogs.ejb;
    import javax.ejb.EJBHome;

    public interface HelloWorldHome extends EJBHome {

    HelloWorldService create() throws java.rmi.RemoteException,javax.ejb.CreateException;

    HelloWorldService createState(Integer id,String name) throws java.rmi.RemoteException,javax.ejb.CreateException;

    }

    里面定义的创建session bean的方法必需遵守createXXX形式,如示例中的create(),createState(...)两个方法,一般stateful的session bean,因为其是有状态的,所以一般在创建的时候把初始化其状态值,所以此createXXX方法一般会有参数,但是stateless的bean是无状态的,如果createXXX方法有参数,则会在容器部署启动时报错。因为现在我们是定义的有状态情况,所以crateState(Integer,String)有参数.

    细心的读者会可能发现了home interface里定义的方法和HelloworldServiceImpl里的ejbCreate()和ejbCreateState(Integer,Strging)两个方法有点关联,确实是这样。如果home里定义crateXXX方法,则要在SessionBean的实现里定义对应的ejbCreateXXX的方法,且参数个数和类型一致。

    客户端用JNDI查找ejb并调用代码如下:

               InitialContext initCtx = new InitialContext(env);
    Object obj=initCtx.lookup("FirstEjb");
    HelloWorldHome home=(HelloWorldHome)PortableRemoteObject.narrow(obj,HelloWorldHome.class);
    //当不传任何参数时
    HelloWorldService hello = home.create();
    String s = hello.getHello();
    System.out.println(s);
    //当传达参数时
    HelloWorldService hello1 = home.createState(1,"tony");
    String s1 = hello1.getHello();
    System.out.println(s1);

    其实当调用createXXX方法时,ejb容器执行如下操作,首先用sessionbean的类(HelloWorldServiceImple.class)newInstance一个实例,然后调用setSessionContext方法把容器的sessionContext对象传进去,然后根据客户调用的createXXX(create和createState)方法来调用ejbCreateXXX(ejbCreate和ejbcreateState)方法。

    到此,这个ejb的Demo可以打成jar包并部署到ejb容器中发布了,并用一个远程机器进行调用。当然还要进行相关配置(标准ejb配置ejb-jar.xml)

    下载地址:https://files.cnblogs.com/jcli/ejb.zip


  • 相关阅读:
    Vs2017添加引用时报错未能正确加载“ReferenceManagerPackage”包。
    Java中数组复制的几种方法
    Java类的执行顺序
    JVM——代空间的划分
    JVM——垃圾收集器
    Java异常体系结构
    设计模式——单例模式
    Java多线程系列——原子类的实现(CAS算法)
    乐观锁与悲观锁
    Java中Volatile关键字详解
  • 原文地址:https://www.cnblogs.com/jcli/p/2379734.html
Copyright © 2011-2022 走看看