UML软件工程组织

我的EJB学习历程 (五)
来自 AGainsT ALL oDDs
 

哈哈,过了一个轻松的周末,又要开始写东西咯。

周末本来也想写,可是还是觉得玩有意思,姑且放几天假。

 

上次讲的是无状态会话BEAN

好象还是有点不明白为什么要分无状态和状态会话BEAN这两种BEAN,不过不要紧,看完状态会话BEAN的程序就能明白了。对了,还有一点要说的。我周五那天搞了一天的ECLIPSE3,听说他出新版本了,所以赶紧下载试验试验,他在里边新加了功能叫EJB EDITOR,这个东西不错,有好多新东西。可是唯一另我费解的是为什么用他CREATE CLIENT TEST PROGRAMM的时候却总是报错!所以还是比较的烦躁的!也不知道是ECLIPSE的毛病还是我机器自己运行环境的毛病,大家也试试然后告诉我啊!

 

我的这个状态会话BEAN还是用ECLIPSE2.1写的拉。

我先把程序写给大家,然后再分析吧,我好象是那种喜欢先看程序然后再看理论的人。不知道是不是有人和我一样。

 

这是客户端的实现程序:

package com.test.session;

 

import javax.ejb.*;

 

/**

 * @ejb.bean name="Stateful"

 *  jndi-name="StatefulBean"

 *  type="Stateful"

 *

 *--

 * This is needed for JOnAS.

 * If you are not using JOnAS you can safely remove the tags below.

 * @jonas.bean ejb-name="Stateful"

 *  jndi-name="StatefulBean"

 *

 *--

 **/

 

public abstract class StatefulBean implements SessionBean {

 

/**

 * @ejb.create-method

 *  view-type="remote"

**/

public void ejbCreate(double amout) throws CreateException{

    this.amout=amout;

}

/**

 * @ejb.interface-method

 *  view-type="remote"

**/

public void addFunds(double amout){

    this.amout+=amout;

}

/**

 * @ejb.interface-method

 *  view-type="remote"

**/

public void withdrawFunds(double amout){

    this.amout-=amout;

}

/**

 * @ejb.interface-method

 *  view-type="remote"

**/

public double getBalance(){

 return this.amout;

}

 

double amout;

 

}

 

对了,ejbCreate(double amout)方法是在BEAN生成过程中,容器调用ejbCreate(double amout)方法的。

就好象是初始化的方法一样。

还有你一定要确保在主接口中有个Create(double amout)方法和ejbCreate(double amout)对应啊!这段是必须的,如果不明白的话,赶紧找资料。你这个ejbCreate(double amout)方法在新建的时候要选择CREATE哦!

 

在把客户端的测试程序给你们:

package com.testing.client;

 

import java.rmi.RemoteException;

import java.util.Hashtable;

 

import javax.ejb.CreateException;

import javax.naming.InitialContext;

import javax.naming.NamingException;

import javax.swing.JFrame;

import javax.swing.*;

import java.awt.*;

import java.awt.event.*;

import java.text.*;

 

import com.test.session.*;

 

/**

 * @author sy

 *

 * 更改所生成类型注释的模板为

 * 窗口 > 首选项 > Java > 代码生成 > 代码和注释

 */

public class testStateful extends JFrame  implements ActionListener{

   

    public testStateful(){

        super("fund manger");

    }

 

    private com.test.session.StatefulHome getHome() throws NamingException {

        return (com.test.session.StatefulHome) getContext().lookup(

            com.test.session.StatefulHome.JNDI_NAME);

    }

    private InitialContext getContext() throws NamingException {

        Hashtable props = new Hashtable();

 

        props.put(

            InitialContext.INITIAL_CONTEXT_FACTORY,

            "org.jnp.interfaces.NamingContextFactory");

        props.put(InitialContext.PROVIDER_URL, "jnp://127.0.0.1:1099");

 

        // This establishes the security for authorization/authentication

        // props.put(InitialContext.SECURITY_PRINCIPAL,"username");

        // props.put(InitialContext.SECURITY_CREDENTIALS,"password");

 

        InitialContext initialContext = new InitialContext(props);

        return initialContext;

    }

    public void CreateFund() {

 

        try {

            myBean = getHome().create(1000);

 

            //--------------------------------------

            //This is the place you make your calls.

            //System.out.println(myBean.callYourMethod());

 

        } catch (RemoteException e) {

            e.printStackTrace();

        } catch (CreateException e) {

            e.printStackTrace();

        } catch (NamingException e) {

            e.printStackTrace();

        }

    }

   

    public void testBean() {

       

            buildGUI();

       

            addWindowListener(new WindowAdapter(){public void WindowClosing(WindowEvent evt){System.exit(0);}});

            CreateFund();

            addFund.addActionListener(this);

            withdraw.addActionListener(this);

            currencyFomat=NumberFormat.getCurrencyInstance();

            try{

            String currency=currencyFomat.format(myBean.getBalance());

            status.setText(msg+currency);

           

            }catch(Exception e){}

       

            pack();

            show();

        }

   

        public void actionPerformed(ActionEvent e){

            String str=amout.getText();

       

            try{

                if(e.getSource()==addFund){

                    myBean.addFunds(Double.parseDouble(str));

                    currencyFomat=NumberFormat.getCurrencyInstance();

                    strBar=currencyFomat.format(myBean.getBalance());

                    status.setText(msg+strBar);

                }

                if(e.getSource()==withdraw){

                    myBean.withdrawFunds(Double.parseDouble(str));

                    currencyFomat=NumberFormat.getCurrencyInstance();

                    strBar=currencyFomat.format(myBean.getBalance());

                    status.setText(msg+strBar);

                }          

           

            }catch(Exception ex){}

        }

       

    public void buildGUI(){

            GridBagLayout gl=new GridBagLayout();

            GridBagConstraints gc=new GridBagConstraints();

            Container container=getContentPane();

            container.setLayout(gl);

       

            gc.fill=GridBagConstraints.BOTH;

            JLabel label=new JLabel("enter amout");

            gl.setConstraints(label,gc);

            container.add(label);

       

            gc.gridwidth=GridBagConstraints.REMAINDER;

            gl.setConstraints(amout,gc);

            container.add(amout);

       

            gl.addLayoutComponent(addFund,gc);

            container.add(addFund);

            gl.addLayoutComponent(withdraw,gc);

            container.add(withdraw);

       

            status=new JLabel(msg);

            gl.addLayoutComponent(status,gc);

            container.add(status);     

       

       

       

       

       

       

        }

   

 

   

        double balance=100;

        JTextField amout=new JTextField(10);

        JButton addFund=new JButton("add funds");

        JButton withdraw=new JButton("withdraw funds");

        String msg="current funds is:";

   

        String strBar="0";

   

        JLabel status;

   

    Stateful myBean;

   

        NumberFormat currencyFomat;

 

    public static void main(String[] args) {

        testStateful test = new testStateful();

        test.testBean();

 

    }

}

 

看出来门道了吗?我终于知道为什么这个要叫做:状态会话BEAN了。因为,因为。。。。。哈哈,他有个amout变量,这个完全是EJB内部的变量,在EJB容器中保存!而和那个无状态会话BEAN不一样的地方就是,无状态会话BEAN是在客户端保存数据。很大的区别!这就是问题的关键!也不知道你们看懂了没有!反正我觉得真的很明显。

 

下边这个是我在IBM文章库里找的一副图,感觉不错,完全讲明白了状态BEAN是怎么回事拉:

 

这些是些讲解,和书上的差不多,省得我打字了。

有状态会话 Bean 生命周期:

  • Bean 在下列情况下被回收:
    • 超时 (无论是激活的或钝化的)
    • 被调用 remove()
  • Passivation 是根据 Least-Recently-Used 算法
  • Activation 由对 Bean 的方法调用产生
  • afterBegin()
    beforeCompletion()
    afterCompletion()
    方法仅对实现 SessionSynchronization 接口的 Bean 有效
  • 在一个事务环境下,调用的方法必需具有相同的事务类型

OK,状态会话BEAN就是这么回事。应该是很简单的东西,完全可以理解。

 

版权所有:UML软件工程组织