近日闲来无事,结合平时项目开发使用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.1 +Spring 2.5.1+ibatis2.3整合开发而成,这与我以前发布的版本中最大特色是整合了Spring2.5.1中的注解功能和半自动化工具ibatis技术,这是本示例的两大特色,简化了配置...
spring=非标准的J2EE技术实现(很多开源的Framwork)。 Sun标准:J2EE技术,Servlet、JSP、JPA、JTA、JavaMail、EJB、JSF、JDBC和JPA。。...struts+spring+ibatis struts+spring+jdbc webWork+spring+
2. **插件架构**:Struts2支持多种插件,如Freemarker和JSP作为视图技术,Hibernate和iBatis作为持久层框架。 3. **OGNL(Object-Graph Navigation Language)**:Struts2使用OGNL作为表达式语言,用于在Action和...
16.2 协同使用Spring和WebWork 2/Struts 2 16.3 集成Spring和Tapestry 16.3.1 集成Spring和Tapestry 3 16.3.2 集成Spring和Tapestry 4 16.4 协同使用Spring和JSF 16.4.1 解析JSF管理的属性 16.4.2 解析Spring...
在Java开发领域,这些技术是构建企业级应用的基石,它们分别是Hibernate、Spring、Struts、MySQL、Oracle、JBoss、Log4j和iBatis。让我们逐一深入了解这些技术及其jar文件的重要性。 1. Hibernate:这是一个强大的...
2. Spring 2.0 的新特性 2.1. 简介 2.2. 控制反转(IoC)容器 2.2.1. 更简单的XML配置 2.2.2. 新的bean作用域 2.2.3. 可扩展的XML编写 2.3. 面向切面编程(AOP) 2.3.1. 更加简单的AOP XML配置 2.3.2. 对@AspectJ 切面的...
16.2协同使用spring和webwork2/struts2 16.3集成spring和tapestry 16.3.1集成spring和tapestry3 16.3.2集成spring和tapestry4 16.4协同使用spring和jsf 16.4.1解析jsf管理的属性 16.4.2解析springbean 16.4.3...
通过使用 Spring AOP,不用依赖 EJB 组件,就可以将声明性事务管理集成到应用程序中。 Spring DAO:JDBC DAO 抽象层提供了有意义的异常层次结构,可用该结构来管理异常处理和不同数据库供应商抛出的错误消息。异常...
Spring 2.0的'spring-jdo.jar', 'spring-jpa.jar', 'spring-hibernate3.jar', 'spring-toplink.jar' 和 'spring-ibatis.jar' 被合并到Spring 2.5大粒度的'spring-orm.jar'中。 Spring 2.5的 'spring-test.jar' 取代...
通过使用JPA,开发者可以在不更改大量代码的情况下切换底层的ORM实现,如EJB、TopLink或iBatis等,从而达到ORM统一的目标。这使得开发团队能够在不同项目中更加灵活地选择最适合的持久化策略,减少迁移成本。 #####...
2. Spring 2.0 的新特性 2.1. 简介 2.2. 控制反转(IoC)容器 2.2.1. 更简单的XML配置 2.2.2. 新的bean作用域 2.2.3. 可扩展的XML编写 2.3. 面向切面编程(AOP) 2.3.1. 更加简单的AOP XML配置 2.3.2. 对@...
16.2 协同使用Spring和WebWork 2/Struts 2 16.3 集成Spring和Tapestry 16.3.1 集成Spring和Tapestry 3 16.3.2 集成Spring和Tapestry 4 16.4 协同使用Spring和JSF 16.4.1 解析JSF管理的属性 16.4.2 解析Spring...
- **开源框架**:熟练使用Struts1.x/Struts2.x/WebWork/Spring/Hibernate/Ibatis等。 - **分布式开发**:熟练运用EJB、RMI、JNDI等技术。 - **WebService、XML**:能使用XFire和Axis进行开发部署。 - **Web应用...
2. **与其他框架集成**:Spring可以很好地与现有的WebWork、Struts或Tapestry等UI框架配合,通过ApplicationContext和WebApplicationContext进行业务逻辑和前端的集成,同时利用Spring的事务管理服务。 3. **远程...
5. **Spring ORM**:对象关系映射模块整合了多种ORM框架,如JDO、Hibernate和iBatis SQL Map,提供了统一的事务管理和DAO异常处理。这使得开发者可以选择最适合项目需求的ORM工具。 6. **Spring Web模块**:这个...
- **汽车4S服务系统**:使用Spring2.0+Ibatis+Struts2+Jquery+Mina+Velocity框架开发,实现客户管理、商机管理、消息管理、广告管理、优惠专栏、跟踪服务和配件管理等功能。 12. **技术应用**: - 在4S服务系统...
Struts 2与Spring框架的集成也是其一大亮点,允许开发者利用Spring的强大功能,如依赖注入(DI)和面向切面编程(AOP),进一步提升代码的可维护性和可测试性。此外,Struts 2还提供了与Hibernate、iBatis等ORM框架...
Spring也可以与其他框架如Struts、EJB、JavaServer Faces、Flex等组合使用,以构建不同的解决方案。 轻量级容器和重量级容器的区别在于,重量级容器如Java EE服务器,通常是独立运行的,包含全套服务,但可能需要...
为了进行开发,你需要将这些jar包添加到项目的类路径中,然后按照框架的配置要求进行相应的设置,例如配置Spring的bean定义文件、Struts2的配置文件以及iBATIS的数据源和映射文件。此外,可能还需要进行Seam的上下文...
Spring是以反向控制设计原理为基础,无需EJB而功能依然强大的轻量级J2EE开发框架。Spring大大简化了使用接口开发的复杂性,并且加快和简化了应用系统的开发。使用简单JavaBean就可以得到EJB的强大功能。 本书介绍了...