该文章在<<EJB编程指南>>的实例的基础上建立的,主要是给新手一个比较直观的例子和作为自己的日志,并不打算介绍EJB的原理性的东西。另外,由于本人水平有限,请不吝赐教。
笔者使用的IDE为:Eclipse3.0+MyEclipse4.01GA
J2EE容器为:JBoss4.0
本文描述一个帮助存款和取款的无状态会话Bean的完整开发及部署的过程。步骤如下:
1、编写无状态会话Bean的实现类。
2、编写无状态会话Bean的主接口和组件接口。
3、将Bean汇编成应用程序,编写部署描述项。
4、在EJB服务器上部署应用程序。
5、用Java应用程序进行测试。
上面是主要的过程,有些步骤可以不用手工完成,通过IDE可以简化开发过程,如果你对IDE的该功能不太清楚可以参考产品文档(http: //myeclipseide.com/enterpriseworkbench/help/index.jsp?topic=/com.genuitec.myeclipse.doc/html/quickstarts/firstejb/index.html)。
一、新建一个EJB Project,工程名字为FundEJB,其他默认就好。
二、创建Session Bean:
1、在src目录下新建包:qiya.deng.fund.ejb,请注意包名最后一定要以ejb为后缀,因为后面我们需要使用的XDoclet工具。
2、新建SessionBean class,命名为StatelessFundManagerEJB,要需要以EJB为后缀,原因同上,而且根据规范最好是以EJB或是Bean为后缀。
3、配置XDoclet :
右击项目选择Properties,选择MyEclipse-XDoclet,点击Add Stander...,选择Standard EJB。
选中Standard EJB,在ejbxdoclet上点击右键添加Add,在其中选择jboss,因为该例子中使用jboss作为应用服务器。选中jboss,修改下列属性
Version = 4.0
destDir = src/META-INF
修改完毕,点击OK按钮回到主窗口。
4、运行Xdoclet:
右击项目选择MyEclipse->run Xdoclet。运行是console窗口会产生提示信息,运行完毕可以看到目录结构发生变化。
5、编辑实现类StatelessFundManagerEJB:
在编辑StatelessFundManagerEJB类之前选观察下StatelessFundManager接口,一定可以发现这个远程组件接口的接口方法和StatelessFundManager的方法是有对应关系的。
在StatelessFundManager.java文件最后添加:
/**
*
* @param balance
* @param amount
* @return
*
* @ejb.interface-method
*/
public double addFunds(double balance,double amount){
balance += amount;
return balance;
}
/**
*
* @param balance
* @param amount
* @return
* @throws InsufficientBalanceException
*
* @ejb.interface-method
*/
public double withdrawFunds(double balance,double amount)throws InsufficientBalanceException {
if (balance < amount) {
throw (new InsufficientBalanceException());
}
balance -= amount;
return balance;
}
重复第4步运行Xdoclet,之后观察StatelessFundManager接口。
6、部署该应用到EJB服务器:
部署描述项在IDE自动生成了,该文件的位置在/META-INF/ejb-jar.xml。打开ejb-jar.xml,jboss.xml文件描述进行查看。
利用MyEclipse提供的部署工具进行部署:
然后运行JBoss容器,可以看到有如下信息提示:
关于MyEclipse中Application Server的使用请查看文档(http://www.myeclipseide.com/images/tutorials/quickstarts/appservers/)。
到现在为止,你已经发布了一个简单的无状态的会话Bean。下面写个简单的应用程序进行测试.
三、编写进行测试的Java客户端程序。
客户端程序可以是Web程序也可以是Application应用程序。这里以Application应用程序为例。
同样使用Eclipse,新建Java Project,这里命名为FundClient。右击该项目选择properties->Java Build path,在Projects中加入上面的Project:FundEJB。在Libraries中点击Add External JARs...,把$JBoss_Home/client的目录下的所有jar文件添加到Libraries中。
最后,就是编写客户端代码:
package qiya.deng.client;
//import省去
public class StatelessFundManagerTestClient extends JFrame implements
ActionListener {
double balance = 0;
JTextField amount = new JTextField(10);
JButton addFunds = new JButton("Add Funds");
JButton withdrawFunds = new JButton("Withdraw Funds");
String msg = "Current account balance";
String strBal = "0";
JLabel status;
StatelessFundManager manager;
NumberFormat currencyFormatter;
public StatelessFundManagerTestClient(){
super("Fund Manager");
}
public static void main(String[] args){
new StatelessFundManagerTestClient().init();
}
private void init() {
buildGUI();
addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent event){
System.exit(0);
}
});
addFunds.addActionListener(this);
withdrawFunds.addActionListener(this);
createFundManager();
currencyFormatter = NumberFormat.getCurrencyInstance();
String currencyOut = currencyFormatter.format(0);
status.setText(msg + currencyOut);
pack();
show();
}
private 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 Amount");
gl.setConstraints(label,gc);
container.add(label);
gc.gridwidth = GridBagConstraints.REMAINDER;
gl.setConstraints(amount,gc);
container.add(amount);
gl.setConstraints(addFunds,gc);
container.add(addFunds);
gl.setConstraints(withdrawFunds,gc);
container.add(withdrawFunds);
status = new JLabel(msg);
gl.setConstraints(status,gc);
container.add(status);
}
public void createFundManager(){
try {
Properties prop = new Properties();
prop.put(Context.INITIAL_CONTEXT_FACTORY,"org.jnp.interfaces.NamingContextFactory");
prop.put(Context.PROVIDER_URL,"localhost:1099");
Context initial = new InitialContext(prop);
Object objref = initial.lookup("ejb/StatelessFundManager");//JINI-Name
StatelessFundManagerHome home =
(StatelessFundManagerHome) PortableRemoteObject.narrow(objref,StatelessFundManagerHome.class);
manager = home.create();
} catch (ClassCastException e) {
e.printStackTrace();
} catch (RemoteException e) {
e.printStackTrace();
} catch (NamingException e) {
e.printStackTrace();
} catch (CreateException e) {
e.printStackTrace();
}
}
public void actionPerformed(ActionEvent e) {
if (e.getActionCommand().equalsIgnoreCase("Withdraw Funds")) {
System.out.println("Withdraw Funds");
}
if (e.getActionCommand().equalsIgnoreCase("Add Funds")) {
System.out.println("Add Funds");
}
if (e.getSource().equals(addFunds)){
System.out.println("addFunds");
try {
status.setText(msg + currencyFormatter.format(manager.addFunds(0,Double.parseDouble(amount.getText()))));
} catch (NumberFormatException e1) {
e1.printStackTrace();
} catch (RemoteException e1) {
e1.printStackTrace();
}
}
if (e.getSource().equals(withdrawFunds)){
System.out.println("withdrawFund");
try {
status.setText(msg + currencyFormatter.format(manager.withdrawFunds(100,Double.parseDouble(amount.getText()))));
} catch (NumberFormatException e1) {
e1.printStackTrace();
} catch (RemoteException e1) {
e1.printStackTrace();
} catch (InsufficientBalanceException e1) {
e1.printStackTrace();
}
}
}
}
然后,你可以运行该程序进行测试了:
至此,恭喜你,你已经大功告成,基本上对EJB建立了感性的认识,可以参考资料进行深入的学习了。