EJB总结

来源:互联网 发布:java应届自我介绍 编辑:程序博客网 时间:2024/05/01 15:56

一个实体Bean的实现 

JPA和实体Bean的应用

 

EJB:

Enterprice JavaBeans

EJB是一个用于分布式业务应用的标准服务端组件模型。采用EJB架构编写的应用是可伸缩的、事务性的、多用户安全的。采用ejb编写的这些应用,可以部署在任何支持EJB规范的服务器平台,如jboss、weblogic等。

 

EJB用来干什么?

EJB实际上是用于编写业务层代码。如果大家对于MVC (model-view-controller)结构的应用有所了解的话,我们知道一个基于MVC结构的应用应包含显示层、控制层和业务层, 假设我们采用ejb开发基于MVC结构的应用,那么ejb就是用于开发应用的业务层.

 

EJB的好处

EJB为我们提供了很多在企业开发中需要使用到的服务,如事务管理/安全/持久化/分布式等,因为这些服务由容器提供,无需我们自行开发,这样大大减少了我们的开发工作量.另外EJB提供了强制式分层解耦设计方法

 

EJB3 VS Spring2.5

估计有同学会问,除了EJB,像spring+hibernate同样提供了事务管理/持久化服务,好像没有必要使用ejb.

   如果你的应用不需要分布式能力,确实没有必要使用ejb, 因为spring+hibernate提供了大部分原来只有ejb才有的服务,而且spring提供的有些服务比ejb做的更细致,更周到。

   那么是不是有了spring,EJB3就没有必要存在了?这种说法是不正确的,因为ejb设计的初衷是用于分布式场合而spring一开始就没有打算提供分布式功能。所以两者看似有竞争的关系,但实际上两者的偏重点不一样,像ejb比较适合用于大型企业,因为大型企业一般都会存在多个信息系统,而这些信息系统又相互关联。为了避免业务功能重复开发,实现最大程度的重用,有必要把业务层独立出来,让多个信息系统共享一个业务中心,这样应用就需要具备分布式能力。

 

 

EJB3的运行环境

EJB3.0应用需要运行在EJB容器里,下面是一些JavaEE应用服务器,JavaEE应用服务器包含Web容器和EJB容器。

 

Jboss(4.2.x以上版本)

  是一个成熟的开源的准JavaEE应用服务器,在开源JavaEE应用服务器中所占市场份额第一。如果你打算选用开源的JavaEE应用服务器,那么jboss是最值得选择的。

Glassfish

  是一个开源的JavaEE应用服务器,对JavaEE规范的支持非常好,其运行性能比较高。因为发展时间相对较短,市场占有率比较低。另外,它能否提供稳定的运行性能,还有待时间的考验。但本人对其后期的发展非常看好。绝对跟jboss有的一拼。

  

Weblogic(10以上版本)

  是商业市场占有率第一的商业JavaEE应用服务器,它具有出色的稳定性,并提供了人性化的管理界面,还有企业需要使用到的众多功能。但在ejb3.0领域,本人认为它做的比jboss差些,bug比较多。

  

Sun Application Server(9.0以上版本)

  商业JavaEE应用服务器,如果你打算选用商业应用服务器运行ejb3,这个是不错的选择。

  

Oracle Application Server(10g以上版本)

  商业JavaEE应用服务器,如果你的数据库是oracle,要想兼容性更好,这个是不错的选择。

  

apusic应用服务器  这是国内的商业JavaEE应用服务器,主要在政府中占有一定的市场份额。要批评的是,其向开发人员提供的文档实在太少了

 

注意:Tomcat目前只是Web容器,它不能运行EJB应用。

 

 

EJB中的三种bean

1.会话bean(session bean)

   负责与客户端交互,是编写业务逻辑的地方,在会话bean中可以通过jdbc直接操作数据库,但大多数情况下都是通过实体bean来完成对数据库的操作.

 

2.实体bean(entity bean)

   它实际上属于java持久化规范(简称JPA)里的技术, JPA的出现主要是为了简化现有的持久化开发工作和整合ORM技术,结束现在Hibernate、TopLink等ORM框架各自为营的局面。

 

3.消息驱动bean(message-driven bean)

   它是专门用于异步处理java消息的组件.具有处理大量并发消息的能力.

   

什么是持久化

   在程序退出后信息可以长期保存的一种数据存储技术。

   

存储Java对象的流行方式之一是使用传统的RDBMS。

主流的关系数据库存取技术有如下四类:  

JDBC直接访问数据库

EJB entity bean

JDO技术(Java Data Objects)

第三方O/R工具,如Hibernate, 其它如IBATIS,Castor,Toplink. 

   

   

实体bean

它属于java持久化规范(简称JPA)里的技术,实体bean通过元数据在javabean和数据库表之间建立起映射关系,然后Java程序员就可以随心所欲的使用面向对象的编程思想来操纵数据库。 JPA的出现主要是为了简化现有的持久化开发工作和整合ORM技术,目前实现的JPA规范的主流产品有Hibernate、TopLink和OpenJPA,在jboss中采用了Hibernate 作为其持久化实现产品。

 

添加JPA的配置文件persistence.xml

 

根据JPA规范的要求:

在实体bean应用中,我们需要在应用的类路径下的META-INF目录加入持久化配置文件persistence.xml

Xml代码  收藏代码
  1. <?xml version="1.0"?>  
  2. <persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  3. xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" version="1.0">  
  4.     
  5. </persistence>  
  6.   
  7. <property name="hibernate.hbm2ddl.auto" value="create-drop"/>  
  8. <property name="hibernate.show_sql" value="true"/>  
  9. <property name="hibernate.format_sql" value="true"/>  

 

实体bean只有持久化之后,才可以使用EntityManager对象访问数据库

 

项目使用:

Java代码  收藏代码
  1. @PersistenceContext  
  2.     private EntityManager em;  
  3.       
  4.     @Override  
  5.     public void init() {  
  6.           
  7.         StringBuilder sql = new StringBuilder();  
  8.         sql.append("SELECT DISTINCT S.SERVICE_NAME_EN, I.BOUND_IP");  
  9.         sql.append("  FROM ESB_SERVICE      S,");  
  10.         sql.append("       ESB_SERVICE_AUTH SA,");  
  11.         sql.append("       ESB_APPLICATION  A,");  
  12.         sql.append("       ESB_APP_BOUND_IP I");  
  13.         sql.append(" WHERE S.ID = SA.SERVICE_ID");  
  14.         sql.append("   AND SA.APPLICATION_ID = A.ID");  
  15.         sql.append("   AND A.ID = I.APPLICATION_ID");  
  16.         sql.append("   AND S.ENABLED_FLAG = 'Y'");  
  17.         sql.append("   AND SA.ENABLED_FLAG = 'Y'");  
  18.         sql.append("   AND A.ENABLED_FLAG = 'Y'");  
  19.         sql.append("   AND I.ENABLED_FLAG = 'Y'");  
  20.           
  21.         Query query = em.createNativeQuery(sql.toString());  
  22.         List<Object[]> result = query.getResultList();  
  23.         for(Object[] oa : result){  
  24.             logger.debug(oa[0].toString() + ":" + oa[1].toString());      
  25.             ...  
  26.         }  
  27.     }  
  28.     ...  
  29. }  

 

META-INF下:

persistence.xml:

Xml代码  收藏代码
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <persistence xmlns="http://java.sun.com/xml/ns/persistence"  
  3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  4.     xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"  
  5.     version="1.0">  
  6.     <persistence-unit name="init-ds">  
  7.         <!-- 数据源:server\default\deploy\datasources\visesbdb-ds.xml 中jndi-name为datasources/visesbdb -->  
  8.         <jta-data-source>java:/datasources/visesbdb</jta-data-source>  
  9.     </persistence-unit>  
  10. </persistence>  

或:

Java代码  收藏代码
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <persistence xmlns="http://java.sun.com/xml/ns/persistence"  
  3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  4.     xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"  
  5.     version="1.0">  
  6.     <persistence-unit name="msgreceiver-ds">  
  7.         <jta-data-source>java:/datasources/visesbdb</jta-data-source>  
  8.         <jar-file>com.project.soa.lightesb.bean-2.2.0.jar</jar-file>  
  9.         <properties>  
  10.             <property name="hibernate.hbm2ddl.auto" value="none" />  
  11.             <property name="hibernate.show_sql" value="false" />  
  12.             <property name="hibernate.format_sql" value="false" />  
  13.         </properties>  
  14.     </persistence-unit>  
  15. </persistence>  

  或:

Java代码  收藏代码
  1. <persistence xmlns="http://java.sun.com/xml/ns/persistence"  
  2.  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  3.  xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"  
  4.  version="1.0">  
  5.    
  6.  <persistence-unit name="jboss-eb" transaction-type="JTA">  
  7.   <jta-data-source>java:/MSSQLDS</jta-data-source>  
  8.   <class>org.tibetjungle.javaeee.beginner.ejb.eb.Book</class>  
  9.  </persistence-unit>  
  10.   
  11. </persistence>  

 

 

会话bean

 

无状态会话bean

  平常,我们使用最多的是无状态bean,因为它的bean实例可供多个用户使用,所以它的性能比有状态bean高.正因为一个bean实例被多个用户使用.那么,前一个用户设置的值有可能被后一个用户所修改,所以它无法正确保存某个用户设置的值,因此是无状态的.

 

有状态会话bean

 

有状态bean平常使用的并不多,因为它的一个bean实例只供一个用户使用,所以性能开销比较大,正因为它的实例只被一个用户使用, 用户为它设置的值是不会被其他用户修改,所以可以正确保存用户设置的值,因此是有状态的.

 

 

Session bean的客户端开发 

Java代码  收藏代码
  1. public static void main(String[] args) {  
  2.     Properties props = new Properties();  
  3.     props.setProperty("java.naming.factory.initial""org.jnp.interfaces.NamingContextFactory");  
  4.     props.setProperty("java.naming.provider.url""localhost:1099");  
  5.     try {  
  6.         InitialContext ctx = new InitialContext(props);  
  7.         HelloWorld helloworld = (HelloWorld) ctx.lookup("HelloWorldBean/remote");  
  8.         System.out.println(helloworld.sayHello("佛山"));  
  9.     } catch (NamingException e) {  
  10.         System.out.println(e.getMessage());  
  11.     }  
  12. }  

 

 

设置JNDI访问环境信息

在进行JNDI查找前,我们必须设置应用服务器的上下文信息,主要是设置JNDI驱动的类名(java.naming.factory.initial)和命名服务提供者的URL (java.naming.provider.url) 。

 

java.naming.factory.initial或Context.INITIAL_CONTEXT_FACTORY:

环境属性名,用于指定InitialContext工厂(或JNDI驱动),它类似于JDBC指定数据库驱动类。

因为本例子连接的是JbossNS(命名服务的实现者),所以使用Jboss提供的驱动类:org.jnp.interfaces.NamingContextFactory

 

java.naming.provider.url或Context.PROVIDER_URL:

         环境属性名,包含提供命名服务的主机地址和端口号。它类似于JDBC指定数据库的连接URL。连接到JbossNS的URL格式为:jnp://host:port,该URL的“jnp:”部分是指使用的协议,JBoss使用的是基于Socket/RMI的协议。host为主机的地址,port为JNDI服务的端口。除了host之外,其他部分都是可以不写的。

 

下面是数据库访问例子:

Java代码  收藏代码
  1. Class.forName("org.gjt.mm.mysql.Driver").newInstance();  
  2. Properties props = new Properties();  
  3. props.put("user","root");  
  4. props.put("password","123456");  
  5. Connection conn =  DriverManager.getConnection("jdbc:mysql://localhost:3306/itcast",  props);  

 

如同数据库一样,根据访问命名服务器的不同,为上下文设置的驱动类和URL也是不同的,如下面是访问Sun应用服务器的上下文信息:

Java代码  收藏代码
  1. Properties props = new Properties();  
  2. props.setProperty("java.naming.factory.initial""com.sun.enterprise.naming.SerialInitContextFactory");  
  3. props.setProperty("java.naming.provider.url""localhost:3700");  
  4. InitialContext = new InitialContext(props);  
  5. HelloWorld helloworld = (HelloWorld) ctx.lookup("com.foshanshop.ejb3.HelloWorld");  

 

如果客户端运行在应用服务器内,我们不需要为InitialContext设置应用服务器的上下文信息,也不建议设置。

因为应用服务器启动时会把JNDI驱动类等上下文信息添加进系统属性,创建InitialContext对象时如果没有指定Properties参数,InitialContext内部会调用System.getProperty()方法从系统属性里获取必要的上下文信息。对本例子而言,你可以省略传入props参数,之所以给InitialContext设置参数,目的是引出相关知识点,便于教学。在实际应用中,如果给InitialContext设置了参数,反而会带来不可移植的问题。

 

注:创建InitialContext对象时如果没有指定Properties参数,InitialContext还会在classpath下寻找jndi.properties文件,并从该文件中加载应用服务器的上下文信息。这样避免了硬编码为InitialContext设置Properties参数。

 

jndi.properties的配置如下:

java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory

java.naming.provider.url=localhost:1099

java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces

 

 

 

Jboss默认生成的JNDI 名称

当EJB发布到Jboss 时,如果我们没有为它指定全局JNDI名称或修改过其默认EJB名称,Jboss就会按照默认的命名规则为EJB生成全局JNDI名称,默认的命名规则如下:

 

如果把EJB作为模块打包进后缀为*.ear的JAVA EE企业应用文件,默认的全局JNDI名称是

本地接口:EAR-FILE-BASE-NAME/EJB-CLASS-NAME/local

远程接口:EAR-FILE-BASE-NAME/EJB-CLASS-NAME/remote

       EAR-FILE-BASE-NAME为ear文件的名称,EJB-CLASS-NAME为EJB的非限定类名。

例:把HelloWorld应用作为EJB模块打包进名为HelloWorld.ear的企业应用文件,它的远程接口的JNDI 名称是:HelloWorld/HelloWorldBean/remote

 

如果把EJB应用打包成后缀为*.jar的模块文件,默认的全局JNDI名称是

本地接口:EJB-CLASS-NAME/local

远程接口:EJB-CLASS-NAME/remote

例:把HelloWorld应用打包成HelloWorld.jar文件,它的远程接口的JNDI名称是:HelloWorldBean/remote

 

 

使用注释改变Session Bean的JNDI 名称

 

如果我们没有指定EJB的JNDI名称,当EJB发布到应用服务器时,应用服务器会按默认规则为EJB生成全局JNDI名称。当我们需要自定义JNDI名称时,可以这样做

如果EJB在Jboss中使用,可以使用Jboss提供的 @LocalBinding 和 @RemoteBinding 注释,@LocalBinding注释指定Session Bean的Local接口的JNDI名称,@RemoteBinding注释指定Session Bean的Remote接口的JNDI名称,如下:

Java代码  收藏代码
  1. @Stateless  
  2. @Remote ({Operation.class})  
  3. @RemoteBinding (jndiBinding="foshanshop/RemoteOperation")  
  4. @Local ({LocalOperation.class})  
  5. @LocalBinding (jndiBinding="foshanshop/LocalOperation")  
  6. public class OperationBean implements Operation, LocalOperation {  
  7.   
  8. }  

 

 

使用xml文件改变Session Bean的JNDI 名称

由于JNDI名称与厂商有关,如果使用注释定义JNDI名称会带来移植问题,因此建议使用ejb-jar.xml部署描述文件进行定义,该文件必须放置在jar的META-INF目录下

Xml代码  收藏代码
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <ejb-jar  xmlns=http://java.sun.com/xml/ns/javaee  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  3.       xsi:schemaLocation="http://java.sun.com/xml/ns/javaee  
  4.                           http://java.sun.com/xml/ns/javaee/ejb-jar_3_0.xsd"  version="3.0">  
  5.     <enterprise-beans>  
  6.         <session>  
  7.             <ejb-name>HelloWorldBean</ejb-name>  
  8.             <mapped-name>HelloWorldBean</mapped-name>  
  9.         </session>  
  10.     </enterprise-beans>  
  11. </ejb-jar>  

 

ejb-name为EJB名称,mapped-name为bean的JNDI名称。

 

 

目前jboss不支持在ejb-jar.xml通过mapped-name指定JNDI名称,但我们可以使用他专属的部署描述文件jboss.xml进行定义,如下:

Xml代码  收藏代码
  1. <?xml version="1.0" encoding="UTF-8" ?>  
  2. <!DOCTYPE jboss PUBLIC "-//JBoss//DTD JBOSS 4.2//EN“ "http://www.jboss.org/j2ee/dtd/jboss_4_2.dtd">  
  3. <jboss>  
  4.     <enterprise-beans>  
  5.         <session>  
  6.             <ejb-name>HelloWorldBean</ejb-name>  
  7.             <jndi-name>hello/remote</jndi-name>  
  8.         </session>  
  9.     </enterprise-beans>  
  10. </jboss>  

 

项目中使用:

Java代码  收藏代码
  1. public interface ControlService {  
  2.   
  3.     void init();      
  4. }  
  5.   
  6. @Stateless (name = "ControlService")  
  7. @Local ({ControlService.class})  
  8. public class ControlServiceImpl implements ControlService{  
  9.       
  10.     private static final Logger logger = LoggerFactory.getLogger(ControlServiceImpl.class);  
  11.       
  12.     @PersistenceContext  
  13.     private EntityManager em;  
  14.       
  15.     @Override  
  16.     public void init() {  
  17.         ...  
  18.     }  
  19.     ...   
  20. }  

 

META-INF下:

jboss.xml:

Xml代码  收藏代码
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <jboss>  
  3.     <enterprise-beans>  
  4.         <session>  
  5.             <ejb-name>ControlService</ejb-name>  
  6.             <jndi-name>ESBDaemon/ControlService</jndi-name>  
  7.             <local-jndi-name>ESBDaemon/ControlService/local</local-jndi-name>  
  8.         </session>  
  9.           
  10.         ..  
  11.     </enterprise-beans>  
  12. </jboss>  

 

persistence.xml:

Xml代码  收藏代码
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <persistence xmlns="http://java.sun.com/xml/ns/persistence"  
  3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  4.     xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"  
  5.     version="1.0">  
  6.     <persistence-unit name="init-ds">  
  7.         <!-- 数据源:server\default\deploy\datasources\visesbdb-ds.xml 中jndi-name为datasources/visesbdb -->  
  8.         <jta-data-source>java:/datasources/visesbdb</jta-data-source>  
  9.     </persistence-unit>  
  10. </persistence>  

 

 

通过远程接口调用ejb的过程:

首先客户端需要与ejb建立起socket通信在通信管道上他们之间需要来回发送IIOP协议消息,因为数据要在网络进行传输,存放数据的java对象必须要进行序列化。

在这个过程中我们看到,有网络通信的开销、协议解析的开销、对象序列化的开销。因为ejb是分布式技术,它允许客户端与ejb应用在不同一机器上面,所以这些性能开销也是必然的。但是在实际生产中,不可避免存在这种情况:客户端与EJB应用运行在同一个jboss中。这时候客户端访问ejb是否有必要走上面的网络通信呢?据我们所知,这时候客户端与ejb是在同一个jvm内,他们之间完全可以通过内存进行交互,这样就可以避免网络通信的性能开销。既然我们都想到了这一点,EJB专家组也想到了这一点,所以引入了本地接口。

 

通过本地接口调用ejb,直接在内存中交互,这样就能避免因网络通信所造成的各种性能开销。但是有一点,大家必须注意,只有客户端与EJB应用在同一个JVM内运行的时候,我们才能调用本地接口,否则只能调用远程接口

什么情况下客户端与EJB应用是在同一个JVM?简单地说只要客户端与ejb发布在同一个jboss内,我们就认为他们是在同一个JVM

 

 

开发具有local接口session bean:

Java代码  收藏代码
  1. @Stateless  
  2. @Local ({HelloWorldLocal.class})  
  3. public class HelloWorldBean implements HelloWorldLocal {  
  4.       
  5.     public String say (String name) {          
  6.         return name +"说:你好!世界,这是我的第一个EJB3哦.";  
  7.     }  
  8. }  
  9.   
  10.   
  11. try {  
  12.     InitialContext ctx = new InitialContext();  
  13.     HelloWorldLocal helloworld = (HelloWorldLocal) ctx.lookup("HelloWorldBean/local");  
  14.     out.println(helloworld.sayHello("佛山人"));  
  15. catch (NamingException e) {  
  16.     out.println(e.getMessage());  
  17. }  

 

 

EJB调用机制

由于EJB的调用过程对开发者来说是透明的,以至于我们错误地认为:lookup()方法返回的对象就是bean实例。实际上,客户端与Session bean交互,它并不直接与Bean实例打交道,而是经由bean的远程或本地接口。当你调用远程或本地接口的方法时,接口使用的是存根(stub)对象。该存根实现了sessionbean的远程或本地接口。它负责将方法调用经过网络发送到远程EJB容器,或将请求路由到位于本地JVM内的EJB容器。存根是在部署期间使用JDK所带的java.lang.reflect.Proxy动态生成。

 

第一步:客户端调用远程接口的SayHello()方法(实际上调用的是存根对象的SayHello()方法,该存根实现了HelloWorld的远程接口)。

第二步:方法调用经过IIOP Runtime被转换成CORBA IIOP消息发往应用服务器。

第三步:应用服务器接收到请求消息后,交由骨架(skeleton)处理。骨架通过IIOP Runtime解析协议消息,并根据协议要求调用bean实例的SayHello()方法。

第四步:骨架(skeleton)将SayHello()方法的返回值经过IIOP Runtime转换成CORBA IIOP应答消息发回客户端。

第五步:存根对象通过IIOP Runtime将CORBA IIOP应答消息解析成返回值。

 

 

 

依赖注入(dependency injection)

 

注入ejb:

Java代码  收藏代码
  1. @Stateless  
  2. @Remote (Injection.class)  
  3. public class InjectionBean implements Injection {   
  4.   
  5.        @EJB (beanName="HelloBean")  
  6.        LocalHello helloworld;  
  7.          
  8.        public String SayHello() {  
  9.            return helloworld.SayHello("注入者");  
  10.        }  
  11. }  

 

或:

Java代码  收藏代码
  1. @EJB (mappedName = "ESBDaemon/ControlService/local")  
  2.     private ControlService cs;  
  3.       
  4.     public void contextInitialized(ServletContextEvent sce) {  
  5.         cs.init();  
  6.     }  

 

注入数据源:

Java代码  收藏代码
  1. @Resource(mappedName = "java:/DefaultMySqlDS")  
  2. DataSource myDb;  
  3.   
  4. Connection conn = null;  
  5. try {  
  6.     conn = myDb.getConnection();  
  7.     Statement stmt = conn.createStatement();  
  8.     ResultSet rs = stmt.executeQuery("SELECT studentName FROM student");  
  9.     if (rs.next())  str = rs.getString(1);  rs.close();  
  10.     stmt.close();  
  11. catch (SQLException e) {  
  12.     e.printStackTrace();  
  13. }finally{  
  14.     try {  
  15.         if(null!=conn && !conn.isClosed()) conn.close();  
  16.     } catch (SQLException e) {  
  17.         e.printStackTrace();  
  18.     }  
  19. }  

 

 

在jboss中配置数据源

Java代码  收藏代码
  1. <datasources>  
  2.   <local-tx-datasource>  
  3.     <jndi-name>DefaultMySqlDS</jndi-name>  
  4.     ...  
  5.   </local-tx-datasource>  
  6. </datasources>  

 

 

EJB3 的分布式特点


0 0
原创粉丝点击