近日闲来无事,结合平时项目开发使用EJB2.x过程中带来的种种不便,决定结合Spring深入总结和研究下EJB开发和调用方面技术,主要包括三个方面:
1、事务控制
在Struts2+EJB2+Spring2+Ibatis的技术架构中,有三个地方可以进行事务控制
1)通过EJB2进行全局事务控制,EJB的事务控制分为两种:容器管理事务和Bean管理事务
使用EJB容器管理事务默认启用的是JTA事务,且是基于EJB方法的事务控制,要求在EJB方法包含完成一个业务且需要进行事务控制的各种操作,下边给出一个完整实例。
示例1(将事务完全交由ejb容器进行管理):
Spring的applicationContext.xml文件配置:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">
<!-- 配置远程JNDI数据源-->
<bean id="jndiDataSource" class="org.springframework.jndi.JndiObjectFactoryBean" scope="singleton">
<property name="jndiName" value="xpDS" />
<property name="jndiEnvironment">
<props>
<prop key="java.naming.factory.initial">weblogic.jndi.WLInitialContextFactory</prop>
<prop key="java.naming.provider.url">t3://127.0.0.1:7001</prop>
<prop key="java.naming.security.principal">weblogic</prop>
<prop key="java.naming.security.credentials">weblogic</prop>
</props>
</property>
</bean>
<!-- ibatis sqlMapClient -->
<bean id="sqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
<property name="configLocation" value="classpath:sql-map-config.xml"/>
<property name="dataSource" ref="jndiDataSource"/>
</bean>
<!-- 引入bo配置文件 -->
<import resource="classpath:/config/dmtab.xml" />
</beans>
在Spring的applicationContext.xml文件中未进行任何关于事务管理方面的配置
EJB方法代码:
public class HelloBean implements javax.ejb.SessionBean {
...
public String saveDM_DWLX(DM_DWLX param) {
DM_DWLX temp = new DM_DWLX();
temp.setDWLX_DM("89");
temp.setDWLX_MC("政府机关");
boDM_DWLX.insertDM_DWLX(temp);//保证能够成功插入数据库
boDM_DWLX.insertDM_DWLX(param);//模拟插入失败情况
return null;
}
...
}
注意:这里的两次插入操作都是在ejb方法中进行的,如果将这两次插入操作移植到boDM_DWLX.insertDM_DWLX(DM_DWLX param)方法中完成,那么事务就不能正常回滚了。因此,通过ejb控制事务时,ejb方法就变成了业务方法,封装了一个业务对应的各种操作,和项目技术架构中使用ejb只作为facade和实现分布式的应用相违背,而且,每当业务发生变化都需要修改EJB,为系统修改造成极大的不方便。
ejb-jar.xml文件配置:
<?xml version="1.0" encoding="UTF-8"?>
<ejb-jar id="ejb-jar_1" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/ejb-jar_2_1.xsd" version="2.1">
<description</description>
<display-name>EJBTest</display-name>
<enterprise-beans>
<!-- Session Beans -->
<session id="Session_Hello">
<description><![CDATA[An EJB named Hello]]></description>
<display-name>Hello</display-name>
<ejb-name>Hello</ejb-name>
<home>net.xp.service.ejb.HelloHome</home>
<remote>net.xp.service.ejb.Hello</remote>
<local-home>net.xp.service.ejb.HelloLocalHome</local-home>
<local>net.xp.service.ejb.HelloLocal</local>
<ejb-class>net.xp.service.ejb.HelloBean</ejb-class>
<session-type>Stateless</session-type>
<transaction-type>Container</transaction-type><!--注意:此处选择的是容器管理事务-->
</session>
</enterprise-beans>
<container-transaction><!--容器事务属性配置(必须的,否则事务将无法控制)-->
<description></description>
<method>
<description></description>
<ejb-name>Hello</ejb-name>
<method-name>*</method-name>
</method>
<trans-attribute>Required</trans-attribute>
</container-transaction>
...
</ejb-jar>
客户端测试代码:
public static void main(String[] args) throws Exception {
Properties p = new Properties();
p.put("java.naming.factory.initial", "weblogic.jndi.WLInitialContextFactory");
p.put("java.naming.provider.url","t3://127.0.0.1:7001");
InitialContext ctx = new InitialContext(p);
Object obj = ctx.lookup("Hello");
HelloHome home = (HelloHome)PortableRemoteObject.narrow(obj, HelloHome.class);
Hello hello = home.create();
DM_DWLX model = new DM_DWLX();
model.setDWLX_DM("AAa");//模拟字段长度过长异常
model.setDWLX_MC("AA");
hello.saveDM_DWLX(model);
}
测试结果:
在ejb方法saveDM_DWLX中,第一次插入操作成功,但第二次插入操作失败情况下,事务成功回滚
2)通过Spring2的声明式事务在业务层进行事务控制
Spring提供了两种事务管理方式,即编程式事务和声明式事务,这里主要记录使用声明式事务的配置
Spring声明式事务配置代码:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">
<!-- 配置远程JNDI数据源-->
<bean id="jndiDataSource" class="org.springframework.jndi.JndiObjectFactoryBean" scope="singleton">
<property name="jndiName" value="ds" />
<property name="jndiEnvironment">
<props>
<prop key="java.naming.factory.initial">weblogic.jndi.WLInitialContextFactory</prop>
<prop key="java.naming.provider.url">t3://127.0.0.1:7001</prop>
<prop key="java.naming.security.principal">weblogic</prop>
<prop key="java.naming.security.credentials">weblogic</prop>
</props>
</property>
</bean>
<!-- ibatis sqlMapClient -->
<bean id="sqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
<property name="configLocation" value="classpath:sql-map-config.xml"/>
<property name="dataSource" ref="jndiDataSource"/>
</bean>
<!-- 事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="jndiDataSource"/>
</bean>
<!--jta事务管理器,需要进行全局事务时配置,使用jta事务,要求上面的jndi datasource配置成XA DataSource
<bean id="transactionManager" class="org.springframework.transaction.jta.WebLogicJtaTransactionManager">
</bean>
-->
<!--aop配置,这里主要设置对bo包下的类和业务方法进行事务控制-->
<aop:config>
<aop:pointcut id="defaultServiceOperation" expression="execution(* net.xp.service.bo..*.*(..))"/>
<aop:advisor pointcut-ref="defaultServiceOperation" advice-ref="defaultTxAdvice"/>
</aop:config>
<!--事务通知,针对不同方法配置事务属性-->
<tx:advice id="defaultTxAdvice" transaction-manager="transactionManager">-->
<!-- <tx:advice id="defaultTxAdvice">
<tx:attributes>
<tx:method name="get*" read-only="true" rollback-for="Exception"/>
<tx:method name="select*" read-only="true" rollback-for="Exception"/>
<tx:method name="insert*" propagation="REQUIRED" rollback-for="Exception"/>
<tx:method name="delete*" propagation="REQUIRED" rollback-for="Exception"/>
<tx:method name="save*" propagation="REQUIRED" rollback-for="Exception"/>
<tx:method name="update*" propagation="REQUIRED" rollback-for="Exception"/>
<tx:method name="make*" propagation="REQUIRED" rollback-for="Exception"/>
</tx:attributes>
</tx:advice>
<!-- 引入bo配置文件 -->
<import resource="classpath:/config/dmtab.xml" />
</beans>
使用该配置,事务将在bo层进行控制,符合在业务层进行事务控制的要求,且配置和应用简单,推荐使用该方案进行项目中的事务控制
3)通过IBatis对DAO层的事务进行控制
2、基于Spring的EJB开发
虽然Spring提供了很多帮助实现EJB的类,但实现起来那叫一个麻烦,引用Spring官方文档翻译后中的一段文字:
“与不使用Spring方式的EJB客户端相比,Spring的EJB客户端有一个额外的好处。通常如果要想能随意的在本地和远程EJB调用之间切换EJB客户端代码,是会产生问题的。这是因为远程接口的方法需要声明他们抛出的RemoteException
方法,然后客户端代码必须处理这种异常,但是本地接口的方法却不需要这样。如果要把针对本地EJB的代码改为访问远程EJB,就需要修改客户端代码,增加处理远程异常的代码,反之要么保留这些用不上的远程异常处理代码要么就需要进行修改以去除这些异常处理代码。使用Spring的远程EJB代理,我们就不再需要在业务方法接口和EJB的实现代码中声明要抛出的RemoteException
,而是定义一个相似的远程接口,唯一不同就是它抛出的是RemoteException
, 然后交给代理对象去动态的协调这两个接口。也就是说,客户端代码不再需要与 RemoteException
这个checked exception打交道,实际上在EJB调用中被抛出的RemoteException
都将被
以unchecked exception RemoteAccessException
的方式重新抛出,它是RuntimeException
的一个子类。这样目标服务就可以在本地EJB或远程EJB(甚至POJO)之间随意地切换,客户端不需要关心甚至根本不会觉察到这种切换。当然,这些都是可选的,没有什么阻止你在你的业务接口中声明RemoteExceptions
异常。”
刚开始看到这段文字的确让我感到一种久违的兴奋,但经过编写代码实践却发现根本不是这么回事,实现本地EJB时客户端的确不需要捕获任何异常,但是实现远程EJB时客户端仍然要捕获RemoteException,在官方文档中只提供了本地EJB调用的部分代码,并没有提供远程EJB调用的代码,突然感觉有种被忽悠的感觉,在网上找了很多文章,只有问的,却没见到有回答的,真是让人不解~~
如果有哪位高人知道,可以给我回复,分享你的理解,在此先谢过
3、EJB本地接口和远程接口调用
EJB远程接口调用就不说了,主要说说EJB本地接口调用吧,以前在项目中都使用的是远程接口调用,从来没有使用本地接口调用,想着简单,就随便写了点代码试验一把,不试不知道,一试吓一跳,居然碰了一鼻子的灰,一直报NameNotFoundException。最终将用于调用EJB本地接口的Servlet和ejb打包成EAR包部署后测试成功,一直不理解为什么将web和ejb分别以war和jar方式部署在WebLogic的同一个domain下就不行了呢,呵呵,还得等待好心的高人给予解答~~
推荐一篇相关的文章http://www.iteye.com/topic/270490 供大家参考
分享到:
相关推荐
Struts2、Spring和EJB(Struts2+Spring+EJB,简称SSE)是Java企业级开发中常用的三大框架,它们各自承担着不同的职责,共同构建了一个强大的应用架构。Struts2作为MVC(Model-View-Controller)框架,负责处理用户...
Struts、Spring和EJB3是Java开发中的三个重要框架,它们在企业级应用程序开发中发挥着关键作用。Struts提供了MVC(Model-View-Controller)架构,Spring强化了依赖注入和面向切面编程,而EJB3则是Java EE平台上的...
在IT行业中,Hibernate、Spring、EJB(Enterprise JavaBeans)和Ajax是四个非常重要的技术,它们各自在软件开发的不同方面发挥着关键作用。下面将分别详细介绍这些技术,并探讨它们之间的协同工作方式。 **...
在IT行业中,Spring、Struts和EJB是三个非常重要的框架,它们分别专注于不同领域的应用开发。Spring是一个全面的后端开发框架,提供依赖注入、AOP(面向切面编程)、MVC(模型-视图-控制器)以及大量的企业级服务。...
Struts2、Spring和EJB3是Java Web开发中的三个重要框架,它们分别在MVC模式、依赖注入和企业级服务方面发挥着关键作用。这个压缩包提供的源代码是一个完整的项目示例,展示了如何将这三个框架集成到一个应用程序中。...
Struts 2、Spring 和 EJB 是 Java Web 开发中的三个关键框架,它们共同构建了一个强大的客户端应用程序架构。本文将深入探讨这三个框架如何协同工作,以及它们各自在企业级开发中的角色。 首先,Struts 2 是一个...
1)JSP+javabean+DAO(Ajax:anywhere) 2)Struts+spring+hibernate3(AJax:DOJO) 3)JSF+richfaces+seam+EJB 总共3个完整的实例,并配有需求分析~~~~~~~~,绝对经典!
《JavaEE实用开发指南:基于Weblogic+EJB3+Struts2+Hibernate+Spring》-- part2/3
在"拍卖系统jsf+ejb+jpa"的整合中,我们可以想象以下架构: 1. **用户界面**:JSF作为前端,负责接收用户的请求,展示拍卖品信息,处理拍卖出价等操作。用户可以通过JSF组件进行交互,提交的请求会被JSF生命周期...
【标题】"Struts+Spring+JSF+Hibernate+EJB+XML+WebService+Ajax(part1)" 描述了一个全面的J2EE开发教程,涵盖了多个关键的技术栈,包括但不限于MVC框架Struts,依赖注入框架Spring,JavaServer Faces(JSF),持久...
**J2EE教程详解:构建Struts+Spring+JSF+Hibernate+EJB+XML+WebService+Ajax集成应用** 本教程是关于J2EE开发的一份综合指南,它涵盖了多个核心技术和框架,旨在帮助开发者构建高效、可扩展的企业级应用程序。在这...
### SSH框架和JPA+EJB+JSF框架的比较 #### 一、SSH框架解析 SSH框架是由Struts、Spring和Hibernate三个独立的框架组成的,它们分别负责不同的职责:Struts用于构建MVC架构的表现层;Spring作为核心的依赖注入(DI...
【标题】"Axis2+EJB整合开发 源代码"涉及的是在Java环境中,使用Axis2框架与Enterprise JavaBeans(EJB)技术进行Web服务整合的实践案例。这个标题暗示了我们将深入理解如何将EJB的功能集成到基于Axis2的Web服务中,...
**J2EE教程详解:整合Struts、Spring、JSF、Hibernate、EJB、XML、Web Service与Ajax** 在Java企业级开发中,J2EE(Java 2 Platform, Enterprise Edition)是一个重要的标准,它提供了丰富的框架和技术来构建分布式...
本教程聚焦于J2EE的核心技术和框架,包括Struts、Spring、JSF、Hibernate、EJB、XML、WebService以及Ajax,旨在帮助开发者理解和掌握这些技术,从而能够构建高效、可扩展的应用系统。 **1. Struts框架** Struts是...
EJB+JPA数据库持久层开发实践详解,想必不用多说大家也都知道这本书了,需要的就下载看看,其他的就不多说,行内人员都知道则本书的价值
在本文中,我们将探讨如何将三个流行的Java EE框架——Struts2、EJB3和Spring——集成在一起,形成一个强大的企业级应用。这个整合过程对于初学者来说可能会有些复杂,但通过逐步指导,我们将简化这一过程。我们使用...
在Java EE中,我们通常会用到如Servlet、JSP、EJB等组件。 Spring框架是Java EE开发中的核心组件,它提供了一个全面的基础设施,支持创建企业级Java应用程序。Spring的核心特性包括依赖注入(DI)和面向切面编程...
【ejb3+spring+struts实现简单银行系统】 在Java开发领域,EJB(Enterprise JavaBeans)3、Spring框架和Struts框架是常见的企业级应用开发技术,它们结合使用可以构建高效、可扩展的Web应用程序,特别是对于复杂的...