ejb3.0学习笔记1----无状态bean开发

本文详细介绍了EJB3.0中无状态Session Bean的开发过程,包括仅具有Remote接口和Local接口的Bean。无状态Bean是一个简单的POJO,由EJB3.0容器自动实例化和管理。开发步骤包括定义接口、实现接口并添加注解。客户端通过JNDI查找访问EJB,JNDI名称遵循特定规则。同时,文章还讨论了Local接口和Remote接口的区别以及如何在不同环境下使用。

开发只存在Remote 接口的无状态Session Bean
步骤如下:
第一步:要定义一个会话Bean,首先需要定义一个包含他所有业务方法的接口。这个接口不需要任何注释,就像
普通的java 接口那样定义。调用EJB的客户端通过使用这个接口引用从EJB容器得到的会话Bean对象stub。接
口的定义如下:
HelloWorld.java

package com.foshanshop.ejb3;
public interface HelloWorld {
public String SayHello(String name);
}
第二步:实现上面的接口并加入两个注释@Stateless , @Remote

第一个注释定义这是一个无状态会话Bean,第二个注释指明这个无状态Bean的remote接口。在使用这两个注释时需要使用一些EJB的类包.经过上面的步骤一个只存在Remote接口的无状态会话Bean就开发完成。无状态会话Bean是一个简单的POJO(纯
粹的面向对象思想的java 对象),EJB3.0容器自动地实例化及管理这个Bean。下面是HelloWorld会话Bean的实
现代码:
HelloWorldBean.java 。实现类的命名规则是:接口+Bean ,如: HelloWorldBean

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 哦.";
}
}
HelloWorld会话Bean开发完了 

 

HelloWorld会话Bean发布成功后,接下来介绍客户端如何访问她。
当一个无状态会话Bean发布到EJB容器时,容器就会自动为她创建一个对象stub,并把她注册进容器的JNDI目录,
客户端代码使用她的JNDI名从容器获得他的stub。通过这个stub,客户端可以调用她的业务方法。例子代码如
下:
Test.jsp
<%@ page contentType="text/html; charset=GBK"%>
<%@ page import="com.foshanshop.ejb3.HelloWorld, javax.naming.*, java.util.Properties"%>
<%
Properties props = new Properties();

props.setProperty("java.naming.factory.initial",
"org.jnp.interfaces.NamingContextFactory");
props.setProperty("java.naming.provider.url", "localhost:1099");
props.setProperty("java.naming.factory.url.pkgs", "org.jboss.naming");
InitialContext ctx;
try {
ctx = new InitialContext(props);
HelloWorld helloworld = (HelloWorld) ctx.lookup("HelloWorldBean/remote");
out.println(helloworld.SayHello("佛山人"));
} catch (NamingException e) {
out.println(e.getMessage());
}
%>

ctx = new InitialContext(props);是设置JNDI访问的环境,本例使用JBoss,所以把环境设为JBoss的上下文环境。
在这里作者要重点说明一下EJB JNDI名称默认的命名规则,命名规则如下:
1> 如果EJB打包进后缀为*.ear 的J2EE 发布文件,默认的JNDI 名称是
访问本地接口:EAR-FILE-BASE-NAME/EJB-CLASS-NAME/local
访问远程接口:EAR-FILE-BASE-NAME/EJB-CLASS-NAME/remote
例:EJB HelloWorld打包进名为HelloWorld.ear 的J2EE 应用,访问她远程接口的JNDI 名是:
HelloWorld/HelloWorldBean/remote
2> 如果EJB应用打包成后缀为*.jar 的发布文件, 默认的JNDI 名称是
访问本地接口:EJB-CLASS-NAME/local
访问远程接口:EJB-CLASS-NAME/remote
例: HelloWorld应用打包成HelloWorld.jar 文件,访问她远程接口的JNDI名称是:HelloWorldBean/remote
另外有一点要注意:EJB-CLASS-NAME 是不带包名的,如com.foshanshop.ejb3.impl.HelloWorldBean只需取
HelloWorldBean。
目前网上很多教材获取JNDI名的方式都过时了,如:
HelloWorld helloworld = (HelloWorld) ctx.lookup(HelloWorld.class.getName());
我们把上面的客户端应用打成war 文件。然后把她拷贝到“[jboss安装目录]/server/all/deploy”目录下。如果war
文件的文件名为 EJBTest.war ,我们可以通过http://localhost:8080/EJBTest/Test.jsp访问客户端。

 

 

开发只存在Local 接口的无状态Session Bean

开发只存在Local接口的无状态会话Bean的步骤和上节开发只存在Remote接口的无状态会话Bean的步骤相同,
两者唯一不同之处是,前者使用@Remote 注释指明实现的接口是远程接口,后者使用@Local 注释指明实现的接口
是本地接口。当@Local 和@Remote 注释都不存在时,会话 Bean 实现的接口默认为Local 接口。如果在本机调用
EJB(确保客户端与EJB 容器运行在同一个JVM),采用Local 接口访问EJB 优于Remote 接口,因为Remote接口
访问EJB 需要经过远程方法调用(RPCs)环节,而Local 接口访问EJB 直接从JVM 中返回EJB 的引用。下面是只存
在Local 接口的无状态会话Bean 代码。
LocalHelloWorld.java
//author:lihuoming
package com.foshanshop.ejb3;
public interface LocalHelloWorld {
public String SayHello(String name);
}
LocalHelloWorldBean.java
//author:lihuoming
package com.foshanshop.ejb3.impl;
import javax.ejb.Local;
import javax.ejb.Stateless;
import com.foshanshop.ejb3.LocalHelloWorld;
@Stateless
@Local ({LocalHelloWorld.class})
public class LocalHelloWorldBean implements LocalHelloWorld {
public String SayHello(String name) {
return name +"说:你好!世界,这是一个只具有Local接口的无状态Bean";
}
}
客户端调用代码:
LocalSessionBeanTest.jsp
<%@ page contentType="text/html; charset=GBK"%>
<%@ page import="com.foshanshop.ejb3.LocalHelloWorld, javax.naming.*, java.util.Properties"%>
<%
Properties props = new Properties();
props.setProperty("java.naming.factory.initial",
"org.jnp.interfaces.NamingContextFactory");
props.setProperty("java.naming.provider.url", "localhost:1099");
props.setProperty("java.naming.factory.url.pkgs", "org.jboss.naming");
InitialContext ctx;
try {
ctx = new InitialContext(props);
LocalHelloWorld helloworld = (LocalHelloWorld)

ctx.lookup("LocalHelloWorldBean/local");
out.println(helloworld.SayHello("佛山人"));
} catch (NamingException e) {
out.println(e.getMessage());
}
%>
上面的客户端代码打包成war文件发布到jboss中。如果你试图在独立的Tomcat服务器中执行客户端代码(如何
在独立的Tomcat环境中调用EJB请考照 第二章:在独立的Tomcat 中调用EJB),你将获得如下例外:
java.lang.NullPointerException
org.jboss.ejb3.stateless.StatelessLocalProxy.invoke(StatelessLocalProxy.java:74)
产生此例外的原因是,调用Local接口的客户端与EJB容器不在同一个VM(虚拟内存堆)。相对于发布到jboss
deploy目录下的客户端应用而言,他与EJB容器运行在同一个VM。如果客户端与EJB容器在不同的VM,只能
通过其Remote接口进行访问。

 

开发存在Remote 与Local 接口的无状态Session Bean
在实际应用中,一个无状态Session Bean都应该实现Remote与Local接口。当会话Bean的某些方法只供EJB
容器内部调用而不对外暴露时,可以把他定义在Local接口。本节介绍如何开发一个具有Remote与Local 接口的
无状态Session Bean。开发前先介绍一下两个接口具有的方法,两者都含有方法Add(int a, int b),而Local接口含
有一个自己的方法:getResult()。下面是例子的源代码。
定义远程接口:Operation.java
//author:lihuoming
package com.foshanshop.ejb3;
public interface Operation {
public int Add(int a, int b);
}
定义本地接口:LocalOperation.java,本地接口具有远程接口的所有方法,另外有自己的方法getResult()
//author:lihuoming
package com.foshanshop.ejb3;
public interface LocalOperation extends Operation {
public int getResult();
}
实现本地接口与远程接口的会话Bean:OperationBean.java

//author:lihuoming
package com.foshanshop.ejb3.impl;
import javax.ejb.Local;
import javax.ejb.Remote;
import javax.ejb.Stateless;
import com.foshanshop.ejb3.LocalOperation;
import com.foshanshop.ejb3.Operation;
@Stateless
@Remote ({Operation.class})
@Local ({LocalOperation.class})
public class OperationBean implements Operation, LocalOperation {
private int total = 0;
private int addresult = 0;
public int Add(int a, int b) {
addresult = a + b;
return addresult;
}
public int getResult() {
total += addresult;
return total;
}
}
JSP客户端:OperationBeanTest.jsp
<%@ page contentType="text/html; charset=GBK"%>
<%@ page import="com.foshanshop.ejb3.Operation, com.foshanshop.ejb3.LocalOperation,
javax.naming.*, java.util.Properties"%>
<%
Properties props = new Properties();
props.setProperty("java.naming.factory.initial",
"org.jnp.interfaces.NamingContextFactory");
props.setProperty("java.naming.provider.url", "localhost:1099");
props.setProperty("java.naming.factory.url.pkgs", "org.jboss.naming");
InitialContext ctx = new InitialContext(props);
try {
Operation operation = (Operation) ctx.lookup("OperationBean/remote");
out.println("通过远程接口调用EJB成功");
out.println("<br>(通过远程接口调用EJB)相加的结果是:"+ operation.Add(1,1));
} catch (Exception e) {
out.println("<br>远程接口调用失败");
}
out.println("<br>==============================================");
Jboss EJB3.0实例教程
版权所有:黎活明
try {
//通过本地接口调用EJB
LocalOperation A = (LocalOperation) ctx.lookup("OperationBean/local");
out.println("<br>(通过本地接口调用EJB)调用A.Add()的结果是:"+ A.Add(1,1));
out.println("<br>调用A.getResult()的结果是:"+ A.getResult());
LocalOperation B = (LocalOperation) ctx.lookup("OperationBean/local");
out.println("<br>(通过本地接口调用EJB)调用B.Add()的结果是:"+ B.Add(1,1));
out.println("<br>调用B.getResult()的结果是:<font color=red>"+ B.getResult() +
"</font>");
} catch (Exception e) {
out.println("<br>本地接口调用失败");
}
%>
把会话Bean及客户端Web应用发布到jboss,客户端的调用结果如下:
通过远程接口调用EJB成功
(通过远程接口调用EJB)相加的结果是:2
==============================================
(通过本地接口调用EJB)调用A.Add()的结果是:2
调用A.getResult()的结果是:2
(通过本地接口调用EJB)调用B.Add()的结果是:2
调用B.getResult()的结果是:4
细心的你可能会发现调用Local接口时,两次累加的结果都不一样,一个是2,一个是4。调用本地接口的客户端
代码片段如下:
//通过本地接口调用EJB
LocalOperation A = (LocalOperation) ctx.lookup("OperationBean/local");
out.println("<br>(通过本地接口调用EJB)调用A.Add()的结果是:"+ A.Add(1,1));
out.println("<br>调用A.getResult()的结果是:"+ A.getResult());
LocalOperation B = (LocalOperation) ctx.lookup("OperationBean/local");
out.println("<br>(通过本地接口调用EJB)调用B.Add()的结果是:"+ B.Add(1,1));
out.println("<br>调用B.getResult()的结果是:<font color=red>"+ B.getResult() +
"</font>");
你可能认为A和B得到的应该是两个不同的对象,根据OperationBean.java 的代码判断,他们的结果都是2才对。
为何一个为2,另一个为4 呢。
这是因为Stateless Session Bean不负责记录使用者状态,Stateless Session Bean一旦实例化就被加进会话池中,各
个用户都可以共用。即使用户已经消亡,Stateless Session Bean的生命期也不一定结束,它可能依然存在于会话池
中,供其他用户调用。如果它有自己的属性(变量),那么这些变量就会受到所有调用它的用户的影响。

内容概要:本文提出了一种基于非合作博弈理论的居民负荷分层调度模型,并结合双层鲸鱼优化算法(Two-level Whale Optimization Algorithm)进行高效求解,模型与算法均通过Matlab代码实现。研究针对电力系统中居民侧用电负荷的复杂调度问题,引入非合作博弈机制刻画各用户之间的利益竞争关系,实现负荷的分层优化分配;同时设计双层优化架构,上层优化资源配置,下层模拟用户自主决策行为,提升了模型的实用性与合理性。通过智能优化算法求解多层级、非凸非线性的博弈模型,有效提高了调度方案的收敛性与全局寻优能力,适用于现代智能电网中的需求侧管理与能源优化场景。; 适合人群:具备电力系统基础理论知识和Matlab编程能力,从事智能电网、能源优化调度、需求侧管理、博弈论应用等方向的科研人员、高校研究生及工程技术人员。; 使用场景及目标:①应用于居民区电力负荷的分层优化调度系统设计与仿真分析;②为非合作博弈在多主体能源系统建模中的应用提供方法论支持;③利用双层鲸鱼算法解决具有嵌套结构的复杂双层优化问题,提升求解效率与调度方案的可行性。; 阅读建议:建议读者结合提供的Matlab代码深入理解模型构建逻辑与算法实现流程,重点关注博弈模型的效用函数设计、纳什均衡求解思路以及双层优化结构的迭代机制,宜配合实际用电数据开展复现实验以验证模型有效性与鲁棒性。
内容概要:本文围绕基于自适应神经模糊推理系统(ANFIS)智能控制器的可再生能源微电网功率管理系统展开研究,结合Simulink仿真实现,深入探讨了微电网中功率的智能调控与经济机组组合调度问题。通过引入ANFIS控制器,有效应对风能、光伏等可再生能源出力的波动性与不确定性,提升系统运行的稳定性与电能质量。研究内容涵盖微电网多源协调控制策略、功率平衡管理、优化调度模型构建及仿真验证,实现了对分布式电源、储能系统和负荷的协同优化,兼顾经济性与可靠性目标,并通过仿真平台验证了所提方法的有效性与优越性。; 适合人群:具备电力系统、自动化或新能源相关专业背景,熟悉Matlab/Simulink仿真环境,从事微电网能量管理、智能控制、能源优化等领域研究的研究生、科研人员及工程技术人员。; 使用场景及目标:①用于高比例可再生能源接入场景下的微电网能量管理系统研发与教学实践;②为实现微电网功率稳定控制与经济高效运行提供先进的智能控制解决方案;③支撑高水平学术论文复现、科研课题攻关及实际工程项目的仿真验证与方案优化。; 阅读建议:建议结合提供的Simulink模型与相关代码进行动手实践,重点关注ANFIS控制器的设计流程、规则库构建与参数调优方法,并通过与传统PID或MPC控制策略的对比实验,深入理解其在动态响应与鲁棒性方面的优势。同时可进一步拓展文中提出的优化调度逻辑,应用于多目标、多约束的复杂实际应用场景中。
内容概要:本文档聚焦于“直流电机双闭环控制Matlab仿真”,系统阐述了基于Matlab/Simulink平台实现直流电机双闭环控制系统(主要包括速度环与电流环)的设计与仿真全过程。通过构建直流电机的数学模型,结合PI控制器进行调控,实现对电机转速和电枢电流的高精度动态控制,验证控制策略的稳定性与响应性能。文档详细介绍了仿真模型的搭建流程、关键参数的整定方法、系统动态波形的分析手段以及仿真结果的有效性验证,体现了经典自动控制理论在实际电机系统中的工程应用,是电机控制与电力电子技术相结合的典型研究案例。; 适合人群:具备自动控制原理、电机与拖动基础、电力电子技术和Matlab/Simulink仿真能力的电气工程、自动化、机电一体化等专业的本科生、研究生及从事电机驱动系统研发的工程技术人员。; 使用场景及目标:①作为高校课程设计或实验教学材料,帮助学生深入理解双闭环调速系统的工作机理与工程实现;②服务于科研项目,为新型电机控制算法(如滑模、模糊PID等)的开发与性能对比提供基础仿真验证平台;③作为工业界产品前期设计的仿真工具,用于评估不同控制策略在动态响应、抗干扰能力和稳态精度方面的可行性。; 阅读建议:建议读者在学习过程中紧密结合自动控制理论知识,亲手在Simulink环境中搭建完整的双闭环仿真模型,通过反复调整PI控制器的比例与积分参数,观察并分析转速、电流的阶跃响应曲线,从而深刻理解反馈控制的本质、系统稳定性条件以及参数整定对动态性能的影响,进而掌握电机控制系统的设计精髓。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值