﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-同一个目标，同一个梦想-文章分类-EJB</title><link>http://www.blogjava.net/J2EEHOME/category/35701.html</link><description>One Target,One Dream</description><language>zh-cn</language><lastBuildDate>Mon, 10 Nov 2008 01:52:33 GMT</lastBuildDate><pubDate>Mon, 10 Nov 2008 01:52:33 GMT</pubDate><ttl>60</ttl><item><title>实体Bean的BMP和CMP选择</title><link>http://www.blogjava.net/J2EEHOME/articles/239596.html</link><dc:creator>J2EE Home工作室</dc:creator><author>J2EE Home工作室</author><pubDate>Mon, 10 Nov 2008 01:40:00 GMT</pubDate><guid>http://www.blogjava.net/J2EEHOME/articles/239596.html</guid><wfw:comment>http://www.blogjava.net/J2EEHOME/comments/239596.html</wfw:comment><comments>http://www.blogjava.net/J2EEHOME/articles/239596.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/J2EEHOME/comments/commentRss/239596.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/J2EEHOME/services/trackbacks/239596.html</trackback:ping><description><![CDATA[<p>EJB有两种主要类型BMP(Bean managed persistence )和CMP(Container managed persistence ),这两种类型各有优缺点。</p>
<p>BMP是在Bean中完成对数据库JDBC的各种调用，也就是说，在你的实体bean(entity bean)中，明确写入了SQL语句，如"insert .. "或"select ..",并且使用Datasource获得一个数据库资源以及连接(connection)从而对数据库直接进行增加 删除修改。</p>
<p>CMP是由EJB容器自动完成对数据库的操作，你所有做的，就是在实体bean重写入SetXXX或getXXX方法，然后在ejb-jar.xml中定义cmp-field就可以。</p>
<p>很明显,CMP编写要简单多，而且数据库操作由EJB容器完成应该是一种趋势，但是CMP有个缺点就是不够灵活，如果我们要完成类似SQL搜索语句的like命令,如"select * from A where name like '%banqiao'",CMP就无法自动帮助我们完成，这样我们就需要BMP自己来写。</p>
<p>在实际应用，一般为了效率考虑，我们尽量使用CMP，但如何为将来有可能使用BMP作好准备，就是说有可以延伸到BMP的基础。EJB 2.0对CMP的抽象类支持为我们提供了这种实现的基础。</p>
<p>总体思路是，先使用抽象类完成CMP 如果需要BMP 可以extend这个抽象类，然后覆盖原来的方法（用自己的特殊SQL语句操作来覆盖该方法）。</p>
<p>以Java 宠物店(Java Pet Store Demo 1.3)中的地址实体bean:AddressEJB为例:</p>
<table width="100%" border="1">
    <tbody>
        <tr>
            <td bgcolor="#cccccc">public abstract class AddressEJB implements EntityBean {
            <p>private EntityContext context = null;</p>
            <p>// getters and setters for PO CMP fields</p>
            <p>public abstract String getFirstName();<br />
            public abstract void setFirstName(String name);<br />
            public abstract String getLastName();<br />
            public abstract void setLastName(String name);<br />
            public abstract String getStreet1();<br />
            public abstract void setStreet1(String name);<br />
            public abstract String getStreet2();<br />
            public abstract void setStreet2(String name);<br />
            public abstract String getCity();<br />
            public abstract void setCity(String name);<br />
            public abstract String getState();<br />
            public abstract void setState(String name);<br />
            public abstract String getCountry();<br />
            public abstract void setCountry(String name);<br />
            public abstract String getZip();<br />
            public abstract void setZip(String name);</p>
            <p>public Object ejbCreate(String fName, String lName, String s1,<br />
            String s2, String cy, String st,<br />
            String cnty, String pcode)<br />
            throws CreateException {<br />
            setFirstName(fName);<br />
            setLastName(lName);<br />
            setStreet1(s1);<br />
            setStreet2(s2);<br />
            setCity(cy);<br />
            setState(st);<br />
            setCountry(cnty);<br />
            setZip(pcode);<br />
            return null;<br />
            }</p>
            <p>public void ejbPostCreate(String fName, String lName, String street1,<br />
            String street2, String city, String state,<br />
            String country, String zip)<br />
            throws CreateException{}<br />
            public void setEntityContext(EntityContext c){ context = c; }<br />
            public void unsetEntityContext(){}<br />
            public void ejbRemove() throws RemoveException {}<br />
            public void ejbActivate() {}<br />
            public void ejbPassivate() {}<br />
            public void ejbStore() {}<br />
            public void ejbLoad() {}<br />
            }<br />
            </p>
            </td>
        </tr>
    </tbody>
</table>
<p>在上面的AddressEJB中，我们看到只有setXXX或getXXX的方法。</p>
<p>在相应的部署描述文件ejb-jar.xml中我们看到:</p>
<table width="100%" border="1">
    <tbody>
        <tr>
            <td bgcolor="#cccccc">
            <p>&lt;entity&gt;<br />
            　　&lt;display-name&gt;AddressEJB&lt;/display-name&gt;<br />
            　　&lt;ejb-name&gt;AddressEJB&lt;/ejb-name&gt;<br />
            　　&lt;local-home&gt;com.sun.j2ee.blueprints.address.ejb.AddressLocalHome&lt;/local-home&gt;<br />
            　　&lt;local&gt;com.sun.j2ee.blueprints.address.ejb.AddressLocal&lt;/local&gt;<br />
            　　&lt;ejb-class&gt;com.sun.j2ee.blueprints.address.ejb.AddressEJB&lt;/ejb-class&gt;<br />
            　　&lt;persistence-type&gt;Container&lt;/persistence-type&gt;<br />
            　　&lt;prim-key-class&gt;java.lang.Object&lt;/prim-key-class&gt;<br />
            　　&lt;reentrant&gt;False&lt;/reentrant&gt;<br />
            　　&lt;cmp-version&gt;2.x&lt;/cmp-version&gt;<br />
            　　&lt;abstract-schema-name&gt;Address&lt;/abstract-schema-name&gt;<br />
            </p>
            <p>　　&lt;cmp-field&gt;<br />
            　　　　&lt;field-name&gt;firstName&lt;/field-name&gt;<br />
            　　&lt;/cmp-field&gt;<br />
            　　&lt;cmp-field&gt;<br />
            　　　　&lt;field-name&gt;lastName&lt;/field-name&gt;<br />
            　　&lt;/cmp-field&gt;<br />
            　　&lt;cmp-field&gt;<br />
            　　　　&lt;field-name&gt;street1&lt;/field-name&gt;<br />
            　　&lt;/cmp-field&gt;<br />
            　　&lt;cmp-field&gt;<br />
            　　　　&lt;field-name&gt;street2&lt;/field-name&gt;<br />
            　　&lt;/cmp-field&gt;<br />
            　　&lt;cmp-field&gt;<br />
            　　　　&lt;field-name&gt;city&lt;/field-name&gt;<br />
            　　&lt;/cmp-field&gt;<br />
            　　&lt;cmp-field&gt;<br />
            　　　　&lt;field-name&gt;state&lt;/field-name&gt;<br />
            　　&lt;/cmp-field&gt;<br />
            　　&lt;cmp-field&gt;<br />
            　　　　&lt;field-name&gt;country&lt;/field-name&gt;<br />
            　　&lt;/cmp-field&gt;<br />
            　　&lt;cmp-field&gt;<br />
            　　　　&lt;field-name&gt;zip&lt;/field-name&gt;<br />
            　　&lt;/cmp-field&gt;</p>
            <p><br />
            　　&lt;security-identity&gt;<br />
            　　　　&lt;description&gt;&lt;/description&gt;<br />
            　　　　&lt;use-caller-identity&gt;&lt;/use-caller-identity&gt;<br />
            　　&lt;/security-identity&gt;<br />
            <br />
            &lt;/entity&gt;</p>
            </td>
        </tr>
    </tbody>
</table>
<p>在上面部署文件中，标明了Address数据库字段:</p>
<p>firstName,lastName,street1,street2,city,state，country,zip</p>
<p>一旦我们要使用BMP, 只要继承上面的CMP bean:</p>
<p>public class AddressBeanBMP extends AddressEJB {</p>
<p>用我们自己的BMP方法覆盖AddressEJB中的方法:</p>
<p>ejbLoad() --&gt;从数据库中获取数据(SELECT) <br />
ejbStore() --&gt;修改数据库数据UPDATE) <br />
ejbRemove() --&gt;删除数据库数据(DELETE) <br />
ejbCreate() --&gt;插入新的数据记录(INSERT) <br />
ejbFindByPrimaryKey(primary key) --&gt; 确保 primary key 存在.<br />
ejbFindAllPrimaryKey() --&gt;自己的定义 返回一个primary key所有数据记录的collectionxiam</p>
<p>下面以ejbCreate()为例:</p>
<table width="100%" border="1">
    <tbody>
        <tr>
            <td bgcolor="#cccccc">
            <p>public Object ejbCreate(String fName, String lName, String s1,<br />
            String s2, String cy, String st,<br />
            String cnty, String pcode) throws CreateException {<br />
            <br />
            // insert row into database<br />
            this.fName = fName;<br />
            this.lName = lName;<br />
            this.s1 = s1; <br />
            this.s2 = s2; <br />
            this.cy=cy;<br />
            this.st=st;<br />
            this.cnty=cnty;<br />
            this.pcode=pcode; </p>
            <p>// Insert database record<br />
            try {<br />
            Connection connection = getConnection();<br />
            PreparedStatement statement = connection.prepareStatement<br />
            ("INSERT INTO Address (firstName,lastName,street1,street2,city,state，country,zip) VALUES (?, ?, ?,?,?,?)");<br />
            statement.setString(1, fName); <br />
            statement.setString(2, lName); <br />
            statement.setString(3, pcode);<br />
            statement.setString(4, s1);<br />
            statement.setString(5, s2);<br />
            statement.setString(6, st);<br />
            statement.setString(7, cy);<br />
            statement.setString(8, cnty);<br />
            if (statement.executeUpdate() != 1) {<br />
            statement.close();<br />
            connection.close();<br />
            throw new CreateException("Could not create: " );<br />
            }<br />
            statement.close();<br />
            connection.close();<br />
            }<br />
            catch(SQLException e) {<br />
            throw new EJBException("Could not create: " );<br />
            }<br />
            }<br />
            </p>
            </td>
        </tr>
    </tbody>
</table>
<p><br />
<a href="http://www.onjava.com/pub/a/onjava/2002/04/10/j2eedesign.html" target="_blank">J2EE Design Patterns: CMP-to-BMP Pattern </a></p>
<img src ="http://www.blogjava.net/J2EEHOME/aggbug/239596.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/J2EEHOME/" target="_blank">J2EE Home工作室</a> 2008-11-10 09:40 <a href="http://www.blogjava.net/J2EEHOME/articles/239596.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>EJB 3.0规范全新体验</title><link>http://www.blogjava.net/J2EEHOME/articles/237946.html</link><dc:creator>J2EE Home工作室</dc:creator><author>J2EE Home工作室</author><pubDate>Fri, 31 Oct 2008 19:02:00 GMT</pubDate><guid>http://www.blogjava.net/J2EEHOME/articles/237946.html</guid><wfw:comment>http://www.blogjava.net/J2EEHOME/comments/237946.html</wfw:comment><comments>http://www.blogjava.net/J2EEHOME/articles/237946.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/J2EEHOME/comments/commentRss/237946.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/J2EEHOME/services/trackbacks/237946.html</trackback:ping><description><![CDATA[&nbsp;引言　　<br />
　　期待以久的EJB3.0规范在最近发布了它的初稿。在本文中将对新的规范进行一个概要性的介绍，包括新增的元数据支持，EJBQL的修改，实体Bean模型访问bean上下文的新方法和运行时环境等等。作者还讨论了EJB在未来要作出的调整以及EJB3.0与其他开发规范之间的关系。
<p><font face="Times New Roman">　　开始</font></p>
<p><font face="Times New Roman">　　无论如何由于EJB的复杂性使之在J2EE架构中的表现一直不是很好。EJB大概是J2EE架构中唯一一个没有兑现其能够简单开发并提高生产力的组建。EJB3.0规范正尝试在这方面作出努力以减轻其开发的复杂性。EJB3.0减轻了开发人员进行底层开发的工作量，它取消或最小化了很多（以前这些是必须实现）回调方法的实现，并且降低了实体Bean及O/R映射模型的复杂性。</font></p>
<p><font face="Times New Roman">　　在本文中，我首先会介绍EJB3.0中几个主要的改变。它对进一步深入了解EJB3.0是非常重要的。随后，我会从更高的层面来描述已经被提交到EJB3.0规范中的细节，并一个个的讲解新的规范中的改变：实体Bean,O/R映射模型，实体关系模型和EJB QL(EJB查询语言)等等。</font></p>
<p><font face="Times New Roman">　　背景</font></p>
<p><font face="Times New Roman">　　EJB3.0中两个重要的变更分别是：使用了Java5中的程序注释工具和基于Hibernate的O/R映射模型。</font></p>
<p><font face="Times New Roman">　　Java5中的元数据工具</font></p>
<p><font face="Times New Roman">　　Java5（以前叫J2SE1.5或Tiger）中加入了一种新的程序注释工具。通过这个工具你可以自定义注释标记，通过这些自定义标记来注释字段、方法、类等等。这些注释并不会影响程序的语义，但是可以通过工具（编译时或运行时）来解释这些标记并产生附加的内容（比如部署描述文件），或者强制某些必须的运行时行为（比如EJB组件的状态特性）。注释的解析可以通过源文件的解析（比如编译器或这IDE工具）或者使用Java5中的APIs反射机制。注释只能被定义在源代码层。由于所有被提交到EJB3.0草案中的注释标记都有一个运行时的RetentionPolicy，因此会增加类文件占用的存储空间，但这却给容器制造商和工具制造商带来了方便。</font></p>
<p><font face="Times New Roman">　　Hibernate</font></p>
<p><font face="Times New Roman">　　目前Hibernate非常受欢迎，它是开发源代码的Java O/R映射框架，目的是把开发人员从繁琐的数据持久化编程中解脱出来。它也有一个标准的HQL（Hibernate 查询语言）语言，你可以在新的EJB QL中看到它的影子。Hibernate在处理如数据查询、更新、连接池、事务处理、实体关系处理等方面非常简单。</font></p>
<font face="Times New Roman">
<p><br />
&nbsp;&nbsp;&nbsp; 概览</p>
<p>　　在已经提交的EJB3.0规范中主要涉及两个方面的改变：</p>
<p>　　1. 一套以注释为基础的EJB编程模型，再加上EJB2.1中定义的通过部署描述符和几个接口定义的应用程序行为。</p>
<p>　　2. 新的实体Bean持久化模型，EJBQL也有许多重要的改变。</p>
<p>　　还有一些有关上述的提议，比如：一个新的客户端编程模型，业务接口的使用以及实体Bean的生命周期。请注意EJB2.1编程模型（包括部署描述符和home/remote接口）仍然是有效的。新的简化模型并没有完全取代EJB2.1模型。</p>
<p>　　EJB注释</p>
<p>　　EJB规范组织一个重要的目标是减轻原始代码的数量，并且他们为此给出了一个完美而简介的办法。在EJB3.0的里，任何类型的企业级Bean只是一个加了适当注释的简单Java对象(POJO)。注释可以用于定义bean的业务接口、O/R映射信息、资源引用信息，效果与在EJB2.1中定义部署描述符和接口是一样的。在EJB3.0中部署描述符不再是必须的了；home接口也没有了，你也不必实现业务接口（容器可以为你完成这些事情）。</p>
<p>　　比如，你可以使用@Stateless注释标记类把Java类声明为一个无状态会话bean。对于有状态会话bean来说，@Remove注释可以用来标记一个特定的方法，通过这个注释来说明在调用这个方法之后bean的实例将被清除掉。</p>
<p>　　为了减少描述组件的说明信息，规范组织还采纳了由异常进行配置（configuration-by-exception）的手段，意思是你可以为所有的注释提供一个明确的缺省值，这样多数常规信息就可以据此推断得出。</p>
<p>　　新的持久化模型</p>
<p>　　新的实体bean也是一个加了注释的简单Java对象(POJO)。一旦它被EntityManager访问它就成为了一个持久化对象，并且成为了持久化上下文（context）的一部分。一个持久化上下文与一个事务上下文是松耦合的；严格的讲，它隐含的与一个事务会话共存。</p>
<p>　　实体关系也是通过注释来定义的，O/R映射也是，并提供几种不同的数据库规范操作，在EJB2.1中这些要通过开发人员自己的设计模式或者其它技术来完成的（比如，自增长主键策略）。</p>
<p>　　深入研究</p>
<p>　　现在是时候详细了解EJB3.0草案了。让我们开始探讨所有EJB中四种企业级bean，并看看他们在新的规范中是什么样子。</p>
<p>　　无状态会话bean</p>
<p>　　在EJB3.0规范中，写一个无状态会话bean(SLSB)只需要一个简单的Java文件并在类层加上@Stateless注释就可以了。这个bean可以扩展javax.ejb.SessionBean接口，但这些不是必须的。</p>
<p>　　一个SLSB不再需要home接口，没有哪类EJB再需要它了。Bean类可以实现业务接口也可以不实现它。如果没有实现任何业务接口，业务接口会由任意public的方法产生。如果只有几个业务方法会被暴露在业务接口中，这些方法可以使用@BusinessMethod注释。缺省情况下所有产生的接口都是local（本地）接口，你也可以使用@Remote注释来声明这个接口为remote（远程）接口。</p>
<p>　　下面的几行代码就可以定义一个HelloWorldbean了。而在EJB2.1中同样的bean至少需要两个接口，一个实现类和几个空的实现方法，再加上部署描述符。　　</p>
<p>　　mport javax.ejb.*;</p>
<p>　　</p>
<p>　　/**</p>
<p>　　* A stateless session bean requesting that a remote business</p>
<p>　　* interface be generated for it.</p>
<p>　　*/</p>
<p>　　@Stateless</p>
<p>　　@Remote</p>
<p>　　public class HelloWorldBean {</p>
<p>　　　public String sayHello() {</p>
<p>　　　　return "Hello World!!!";</p>
<p>　　　}</p>
<p>　　}</p>
<p>　　</p>
<p>　　有状态会话bean</p>
<p>　　除了几个SFSB的特别说明之外，有状态会话bean(SFSB)和SLSB一样精简：</p>
<p>　　1) 一个SFSB应该有一个方法来初始化自己（在EJB2.1中是通过ejbCreate()来实现的）。在EJB3.0的规范中建议这些初始化操作可以通过自定义方法完成，并把他们暴露在业务接口中。在使用这个bean之前由客户端来调用相应的初始化方法。目前规范组织就是否提供一个注释来标记某个方法用于初始化还存在争议。</p>
<p>　　2) Bean的提供者可以用@Remove注释来标记任何SFSB的方法，以说明这个方法被调用之后bean的实例将被移除。同样，规范组织仍然在讨论是否要有一种机制来处理这种特殊的情况，即当这个方法出现异常的情况下bean的实例是否被移除。</p>
<p>　　下面是对以上问题我个人的观点：</p>
<p>　　1) 是否应该有一个注释来标明一个方法进行初始化呢？我的观点是――应该有，这样容器就可以在调用其他方法之前至少调用一个方法来进行初始化。这不仅可以避免不必要的错误(由于没有调用初始化方法)而且可以使容器更明确的判断是否可以重用SFSB实例。我暂且把这个问题放一放，规范组织只考虑为一个方法提供一个注释来声明它是一个初始化方法。</p>
<p>　　2) 对于第二个问题我的观点也是肯定的。这有利于Bean的提供者合客户端程序对其进行控制。只有一个遗留的问题：那就是一旦调用这个方法失败，是否能移除这个bean 的实例？答案是不能，但是它将会在会话结束的时候被移除。</p>
<p>　　消息驱动Bean</p>
<p>　　消息驱动Bean是唯一一种必须实现一个业务接口的Bean。这个接口指出bean支持的是哪一种消息系统。对于以JMS为基础的MDB来说，这个接口是javax.jms.MessageListener。注意MDB业务接口不是一个真正意义上的业务接口，它只是一个消息接口。</p>
<p>　　实体Bean</p>
<p>　　1) 实体Bean使用@Entity注释来标记，所有实体bean中的属性/字段不必使用@Transient注释来标记。实体bean的持久化字段可以通过JavaBean-style机制或者声明为public/protected字段来实现。</p>
<p>　　2) 实体bean可以使用助手类来描述其状态，但是这些类的实例并没有持久化唯一性（persistent identity）的特性(即，唯一标识这个bean的字段等)，实际上这些助手类与他们的实体bean实例是紧密结合的；并且这些对象还是以非共享方式来访问实体对象的。</p>
<p>　　实体关联</p>
<p>　　EJB3.0同时支持Bean之间双向的合单向的关联，它们可以是一对一、一对多、多对一或者是多对多的关联。然而双向关联的两端还要分为自身端（owning side）和对方端（inverse side）不同的端。自身端负责向数据库通告关联的变更。对于多对多的关联自身端必须明确的声明。实际上对方端通过isInverse=true进行注释（由此自身端就不必说明了而是由另一段推断出）。看来上面的描述，规范组织还能说让EJB变的简单了吗？</p>
<p>　　O/R映射</p>
<p>　　EJB3.0中的O/R映射模型也有了重要的改变，它从原来的abstract-persistence-schema-based变成了现在的Hibernate-inspired模式。尽管目前规范组织还在就此进行讨论但是一个明确的模型将会出现在下一个版本的草案中。</p>
<p>　　举例来说，O/R映射模型将通过bean类中的注释来声明。而且此方法还会指出对应的具体表和字段。O/R映射模型提供了一套自有的SQL；而且除了提供一些基本的SQL外还支持某些高层开发的功能。比如，有一个通过@Column注释声明的字段columnDefinition，那么可以写这样的SQL：columnDefinition="BLOB NOT NULL"　</p>
<p>客户端程序模型</p>
<p>　　一个EJB客户端可以通过@Inject注释以一种&#8220;注入&#8221;的方式获得一个bean的业务接口引用。你也可以使用另一个注释@javax.ejb.EJBContext.lookup()来完成上面的操作，但是规范中没有告诉我们一个普通的Java客户端怎样获得一个Bean的实例，因为这个普通的Java客户端是运行在一个客户端容器中，它无法访问@javax.ejb.EJBContex对象。现在还有另外一种机制来完成上面的工作那就是使用一个超级上下文环境对象：@javax.ejb.Context()。但是规范中没有指出该如何在客户端中使用这个对象。</p>
<p>　　EJB QL</p>
<p>　　EJB QL可以通过@NamedQuery来注释。这个注释有两个成员属性分别是name和queryString.一旦定义了这些属性，就可以通过EntityManager.createNamedQuery(name)来指向这个查询。你也可以创建一个标准的JDBC风格的查询并使用EntityManager.createQuery(ejbqlString)或EntityManager.createNativeQuery(nativeSqlString)(这个方法用于执行一个本地查询)来执行查询。</p>
<p>　　EJB QL有两个地方可以定义其参数。javax.ejb.Query接口提供了定义参数、指向查询、更新数据等等方法。下面是一个EJBQL指向查询的例子：</p>
<p>　　.. ..</p>
<p>　　@NamedQuery(</p>
<p>　　name="findAllCustomersWithName",</p>
<p>　　queryString="SELECT c FROM Customer c WHERE c.name LIKE :custName"</p>
<p>　　)</p>
<p>　　.. ..</p>
<p>　　@Inject public EntityManager em;</p>
<p>　　customers = em.createNamedQuery("findAllCustomersWithName")</p>
<p>　　.setParameter("custName", "Smith")</p>
<p>　　.listResults();</p>
<p>　　</p>
<p>　　下面列出了一些EJB QL的增强特性：</p>
<p>　　1) 支持批量更新和删除。</p>
<p>　　2) 直接支持内连接和外连接。FETCH JOIN运行你指出关联的实体，Order可以指定只查询某个字段。</p>
<p>　　3) 查询语句可以返回一个以上的结果值。实际上，你可以返回一个依赖的类比如下面这样：　　</p>
<p>　　SELECT new CustomerDetails(c.id, c.status, o.count)</p>
<p>　　FROM Customer c JOIN c.orders o</p>
<p>　　WHERE o.count &gt; 100　　</p>
<p>　　4) 支持group by 和having。</p>
<p>　　5) 支持where子句的嵌套子查询。</p>
<p>　　在提交的EJB3.0草案中，EJB QL与标准SQL非常的接近。实际上规范中甚至直接支持本地的SQL(就像我们上面提到的那样)。这一点对某些程序员来说也许有些不是很清楚，我们将在下面进行更详细的讲解。</p>
<p>　　多样性</p>
<p>　　方法许可(Method permissions)可以通过@MethodPermissions或@Unchecked注释来声明；同样的，事务属性也可以通过@TransactionAttribute注释来声明。规范中仍然保留资源引用和资源环境引用。这些一样可以通过注释来声明，但是有一些细微的差别。比如，上下文(context)环境要通过注入工具控制。容器根据bean对外部环境引用自动初始化一个适当的已经声明的实例变量。比如，你可以象下面这样获得一个数据源（DataSource）：　　</p>
<p>　　@Resource(name="myDataSource") //Type is inferred from variable</p>
<p>　　public DataSource customerDB;</p>
<p>　　在上面的例子中如果你不指定引用资源的名称(name)那么其中的customerDB会被认为是默认值。当所有的引用属性都可得到时，@Injec注释就可以这样写：　　</p>
<p>　　@Inject public DataSource customerDB;</p>
<p>　　容器负责在运行时初始化customerDB数据源实例。部署人员必须在此之前在容器中定义好这些资源属性。</p>
<p>　　更好的消息是：那些以前必须检测的异常将一去不复返。你可以声明任意的应用程序异常，而不必在再抛出或捕获其他类似CreateException和FinderException这样的异常。容器会抛出封装在javax.ejb.EJBException中的系统级异常或者只在必要时候抛出IllegalArgumentException或IllegalStateException异常。</p>
<p>EJB文件处理模式</p>
<p>　　在我们结束本节之前，让我的快速的浏览一下容器提供商在EJB处理模式方面可能的变更。规范中对此并没有明确的表态，但我可以想到至少两种模式。</p>
<p>　　1) 一种办法是首先利用EJB文件生成类似于EJB2.1部署模式的文件（包括必要的接口和部署描述符）然后再用类似于EJB2.1的方式来部署这个EJB组件。当然，这样产生的部署描述符可能并不标准但是它可以解决同一个容器对EJB2.1和EJB3.0兼容的问题。　　</p>
<p>　　2) 另一种方法是一种类似于JSP托放的部署模式。你可以把一个EJB文件放到一个预先定义的目录下，然后容器会识别这个EJB并处理它，然后部署并使之可以使用。这种方法可以建立于上面那种方法之上，在支持反复部署时有很大的帮助。考虑到部署的简单性也是EJB3.0规范的目的之一，我真诚的希望在下一个草案出来时能够确定一个模式(至少能有一个非正式的)。</p>
<p>　　你有什么想法？</p>
<p>　　EJB3.0规范的制定正在有序的进行，为了使EJB的开发变得更加容易，EJB规范组织作出的努力是有目共睹的。就像他们说的那样，一切对会变得简单，但做到这一点并不容易。目前已经定义了50个注释标记(还有几个将在下一个草案中发布)，每一个都有自己的缺省规则和其他的操作。当然，我真的不希望EJB3.0变成EJB2.1的一个翻版"EJB 3.0 = EJB 2.1 for dummies"（希望这个等式不要成立）。最后，我还是忍不住要提一些我自己的观点：</p>
<p>　　1) 首先，规范确实使反复部署变得容易了，并且有一个简单的模式来访问运行时环境。我还是觉得home接口应该放弃。</p>
<p>　　2) 在早期的EJB规范中，实体bean用于映射一个持久化存储。理论上(也许只是理论上)可能需要把实体bean映射到一个遗留的EIS(enterprise information system)系统中。出于将来扩展的考虑这样作是有好处的，并且可以使更多的业务数据模型采用实体bean。也因此其伴随的复杂性使得实体bean不被看好。在本次提交的草案中，一个实体bean只是一个数据库的映射。并且是基于非抽象持久化模式和简单的数据访问模式的更加简单开发。</p>
<p>　　3) 我对模型变更持保留态度，我认为在EJB中包含SQL脚本片断并不是个好注意。一些开发人员完全反对包含某些&#8220;SQL片段（SQLness）&#8221;（比如@Table 和 @Column注释）。我的观点是这些SQLness是好的，据此我们可以清楚的知道我们到底要数据库作些什么。但是某些SQL段我看来并不是很好，比如columnDefinition="BLOB NOT NULL"，这使得EJB代码和SQL之间的耦合太过紧密了。</p>
<p>　　4) 尽管对于本地SQL的支持看似很诱人，其实在EJB代码中嵌入SQL是一个非常糟糕的主意。当然，有些办法可以避免在EJB中硬编码SQL，但是这应该在规范中说明，而不能是某些开发人员自己定义的模式。</p>
<p>　　5) 假设@Table注释只用于类。在运行时通过@Table注释的name属性定义的表名称将必须对应一个实际的数据库表。规范对此应该给予清楚的说明和一致的模式。</p>
<p>　　6) 规范还需要更清楚的说明客户端编程模型，尤其是普通java客户端。规范中所有的参考都假设或者隐含的使用EJB客户端。而且规范中对客户端的向后兼容方面也没有给出明确的说法。</p>
<p>　　7) Transient注释应该重新命名以避免和已有的transient关键字发生冲突。事实上，在这一点上我们更乐于稍微的背离一下configuration-by-exception原则并且定义一个@Persistent注释来明确的定义持久化字段。@Persistent注释可以仅仅是一个标记注释或者它可以有几个属性来关联O/R映射注释。</p>
<p>　　与其他规范的关联</p>
<p>　　目前可能影响到EJB3.0的JSR有JSR175（java语言元数据工具）和JSR181（Java Web服务元数据）</p>
<p>　　JSR175已经初步完成并且不会和EJB3.0有太大的冲突；但是JSR181与EJB3.0有两个关联的地方：</p>
<p>　　1) Web service接口：EJB规范将采用一种机制适应JSR181以便可以把一个bean实现为一个Web service并告诉Web service如何被客户端调用。</p>
<p>　　2) JSR 181计划采用不同的机制来处理安全问题。在早期的规范中EJB建议使用一个一致的机制（MethodPermissions），但是JSR 181计划使用一个稍微不同的方式（SecurityRoles和SecurityIdentity注释）。同样的RunAs注释的定义也存在这些许差别。这一问题还在解决中最终会在J2EE层的规范中维持其一致性。</p>
<p>　　在J2EE 1.5中的一些开发规范可能与EJB3.0有关联。除了上面说到的几个关联之外现在没有其他的开发规范与EJB3.0有冲突。</p>
<p>　　结束语</p>
<p>　　在使EJB的开发变得简单高效之前，我们还有很长一段路要走。规范组织在降低EJB的开发难度方面起了个好头。O/R映射模型的提议还处在早期阶段，规范组织正在完善它。我希望它不要太复杂也不要与SQL过分的耦合。让我们不要只是停留在期望、希望、思考和请求中：提出你的想法并把你的建议发送给规范组织ejb3-feedback@sun.com。JCP并不是很民主的组织，但是你的建议一定是有价值的。</font></p>
<img src ="http://www.blogjava.net/J2EEHOME/aggbug/237946.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/J2EEHOME/" target="_blank">J2EE Home工作室</a> 2008-11-01 03:02 <a href="http://www.blogjava.net/J2EEHOME/articles/237946.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>无状态Enterprise JavaBeans的观点</title><link>http://www.blogjava.net/J2EEHOME/articles/237945.html</link><dc:creator>J2EE Home工作室</dc:creator><author>J2EE Home工作室</author><pubDate>Fri, 31 Oct 2008 19:01:00 GMT</pubDate><guid>http://www.blogjava.net/J2EEHOME/articles/237945.html</guid><wfw:comment>http://www.blogjava.net/J2EEHOME/comments/237945.html</wfw:comment><comments>http://www.blogjava.net/J2EEHOME/articles/237945.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/J2EEHOME/comments/commentRss/237945.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/J2EEHOME/services/trackbacks/237945.html</trackback:ping><description><![CDATA[<div id="article">
<p><font face="Verdana">在Component-Base和N-Tier潮流下，无状态（stateless）物件扮演着重要的角色。stateless物件是 OO 和Transaction Service两项技术结合的产物。OO 技术强调的是弹性（felxibility）、重用性（reusability）和分散性(distribution)，Transaction Service技术强调的是效率（performance）和延展性（scalability）。 Stateless物件是这两项技术结合的重要支柱。</font></p>
<p><font face="Verdana">　　传统的OO技术大多着重于 Stateful 物件，然而在今天的MiddleWare（如EJB和 COM+/MTS）里面，Stateless物件的地位却远远高于Stateful物件。尤其是在EJB的架构里，Stateless有着非常重要的用途。例如Stateless的Session物件不需要长期保存自身的状态值，也不专属于特定的用户（client），所以占用的服务器资源非常之少，也由于不隶属于特定的用户，所以许多EJB物件可以共用少数的Stateless物件。</font></p>
<p><font face="Verdana">　　Stateless物件的特性</font></p>
<p><font face="Verdana">　　就Client而言，在意的是server物件的外在行为，而行为又和物件的状态无关。所以client物件不必在意物件状态的变化，而不是此 种物件真的没有状态。比如说stateless的限制并不意味着stateless的session beans不能拥有属性变量，所以，这些session beans一样会拥有自己的内部状态，然而重要的是，client不会看到这些内部状态。</font></p>
<p><font face="Verdana">　　在Internet时代里，资讯系统的扩展性（scalability）显得无比重要，而高度扩展性的前提是必须有效运用Server的资源，而无状态的物件的资源共用性极大地减少了服务器的负载，因此，在开发N-Tier系统的时候，活用Stateless物件是系统开发人员必须具有的技能之一。</font></p>
<p><font face="Verdana">　　使用Stateless支持交易</font></p>
<p><font face="Verdana">　　当企业资讯系统的Client数目大幅度增加的时候，每个Client能够享有的共用资源（shared resources）自然会更加稀少。面对这个问题，除了投入更多的资源之外，好好协调以避免资源的浪费，达到充分共享，也是重要的解决之道。</font></p>
<p><font face="Verdana">　　其中，数据库是最典型的稀有共享资源，交易是协调这项共享资源的可靠技术，如果加上Stateless物件，交易就会更加具有威力--更有效运用数据库的connection，并能跨越不同的数据库（即分布式交易）。</font></p>
<p><font face="Verdana">　　交易是商业往来或异动的事件（event） 。事件一旦发生，企业资讯系统就会参与进行一连串的作业过程（process），在这个过程中，会导致共享资源（比如数据库的资料）的一连串异动。为了确保在异动过程中，不受到别的交易的干扰，也为了确保异动过程中的例外处理（比如roll back），&#8220;交易&#8221;就成为用来管理和协调共用资源的工具。</font></p>
<p><font face="Verdana">　　在交易过程中，需要数据库提供服务（即资源），以便能够异动数据库里面的资料，完毕后就把资源释放，供彼得交易使用。在像EJB等系统的交易服务（transaction service）里 ，都必须具备有ACID（atomic,consistency,isolation,duration）四个特性，来做到上述的资源管理功能。</font></p>
<p><font face="Verdana">　　一般来说，必须先取得和数据库的沟通管道（connection） ，才能获得数据库的服务，而数据库的connection又很有限，所以协调connection成为管理数据库资源的重心。让每个client能尽快释放connection成为重要的管理工作。</font></p>
<p><font face="Verdana">　　在交易的进行过程中，会取得所需的数据库连接，一直到交易结束才会释放掉，所以充分运用连接一定要注意两点，一是交易的时间越短越好，交易越短就能越快速地释放被占用的connection。二是交易所需要的connection越少越好，这样就有更多的共享机会了。</font></p>
<p><font face="Verdana">　　在component-based环境中，一个交易通常由一群物件所共同合作，每个物件可能由不同人所设计开发，每个物件也都可能向数据库索取connection。如果一个交易的参与物件越多，而且每个物件占用的connection时间越长，则这个交易就需要足够多的connection才能完成任务。</font></p>
<p><font face="Verdana">　　因此，&#8220;让物件迅速释放connection&#8221; 是提升数据库资源运用效率的重要策略，stateless物件则是实现这个策略的重要技术。 </font></p>
</div>
<img src ="http://www.blogjava.net/J2EEHOME/aggbug/237945.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/J2EEHOME/" target="_blank">J2EE Home工作室</a> 2008-11-01 03:01 <a href="http://www.blogjava.net/J2EEHOME/articles/237945.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>EJB3应用程序的开发方法</title><link>http://www.blogjava.net/J2EEHOME/articles/237944.html</link><dc:creator>J2EE Home工作室</dc:creator><author>J2EE Home工作室</author><pubDate>Fri, 31 Oct 2008 18:59:00 GMT</pubDate><guid>http://www.blogjava.net/J2EEHOME/articles/237944.html</guid><wfw:comment>http://www.blogjava.net/J2EEHOME/comments/237944.html</wfw:comment><comments>http://www.blogjava.net/J2EEHOME/articles/237944.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/J2EEHOME/comments/commentRss/237944.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/J2EEHOME/services/trackbacks/237944.html</trackback:ping><description><![CDATA[&nbsp;1、EJB3是一个深层次的规范，包含了3个文档，分别面向初级开发者和资深用户。
<p><font face="Times New Roman">&nbsp;&nbsp;&nbsp; 2、EJB3在容器之外使用实体Bean——&gt; 新的容器外持久化特性。</font></p>
<p><font face="Times New Roman">&nbsp;&nbsp;&nbsp; 3、EJB3由JSR220定义：第一个文档：综合介绍新版本的高级特性，着重介绍用于构建EJB组件的新的简化模型；后两个文档：分布讲解核心企业Bean框架和持久化模型的技术细节。</font></p>
<p><font face="Times New Roman">&nbsp;&nbsp;&nbsp; （1） EJB3简化API（EJB3 Simplified API）高度概括新EJB3开发模型；</font></p>
<p><font face="Times New Roman">&nbsp;&nbsp;&nbsp; （2） EJB3核心约定和要求（EJB3 Core Contracts and Requirement）重点讲解会话Bean和消息驱动Bean；</font></p>
<p><font face="Times New Roman">&nbsp;&nbsp;&nbsp; （3） Java持久化API（Java Persistence API）讲解实体和持久化框架。</font></p>
<p><font face="Times New Roman">&nbsp;&nbsp;&nbsp; 4、EJB3包括会话Bean和消息驱动Bean，实体Bean由持久化提供器管理（已经不再是EJB容器管理）。</font></p>
<p><font face="Times New Roman">&nbsp;&nbsp;&nbsp; 5、EJB框架：EJB组件操作的支持环境，包括容器事务、安全事务、资源的池管理和缓存、组件生命周期服务和并发支持等。</font></p>
<p><font face="Times New Roman">&nbsp;&nbsp;&nbsp; 6、EJB核心特性：</font></p>
<p><font face="Times New Roman">&nbsp;&nbsp;&nbsp; （1） 声明式元数据：使用注释或XML文件声明式地指定企业Bean和实体的行为；</font></p>
<p><font face="Times New Roman">&nbsp;&nbsp;&nbsp; （2） 只有在需要非默认行为时，才显示的指定注释或XML——&gt;Configuration by Exception（按异常配置）；</font></p>
<p><font face="Times New Roman">&nbsp;&nbsp;&nbsp; （3） 可伸缩性：EJB服务器使用资源池达到对象重用的最大化，使用持久化缓存避免重复查询或创建相同的对象；</font></p>
<p><font face="Times New Roman">&nbsp;&nbsp;&nbsp; （4） Java事务API（JTA）：分布式事务定义标准API，并且EJB服务器作为EJB的JTA事务管理器；</font></p>
<p><font face="Times New Roman">&nbsp;&nbsp;&nbsp; （5） 多层安全</font></p>
<p><font face="Times New Roman">&nbsp;&nbsp;&nbsp; （6） 可移植性：EJB可移植到实现EJB的任何AS上；</font></p>
<p><font face="Times New Roman">&nbsp;&nbsp;&nbsp; （7） 可重用性：可重用或打包到多个应用程序中；</font></p>
<p><font face="Times New Roman">&nbsp;&nbsp;&nbsp; （8） 持久性：实体Bean——&gt; 在EJB中替换为POJO. 7、XML和注释，同时使用时XML配置文件优先。</font></p>
<p><font face="Times New Roman">&nbsp;&nbsp;&nbsp; 8、依赖注入：在JavaEE容器内实例化一个EJB之后，且在把安全交付给客户之前，容器可以按照此企业Bean定义的原则初始化实例的属性数据。</font></p>
<p><font face="Times New Roman">&nbsp;&nbsp;&nbsp; 9、拦截器：回调方法。企业Bean或实体Bean在遇到特定的生命周期事件时，指定调用它们自己的或其它特定类的方法。</font></p>
<p><font face="Times New Roman">&nbsp;&nbsp;&nbsp; 10、POJO实现：默认的构造器替换了早期EJB要求的ejbCreate（）方法。实体Bean的Home接口比替换为EntityManager接口，它是单一实例工厂，管理实体生命周期的操作。</font></p>
<p><font face="Times New Roman">&nbsp;&nbsp;&nbsp; 11、分布式计算模型12、EJB角色</font></p>
<p><font face="Times New Roman">&nbsp;&nbsp; （1） 企业Bean提供者</font></p>
<p><font face="Times New Roman">&nbsp;&nbsp; （2） 应用程序装配值</font></p>
<p><font face="Times New Roman">&nbsp;&nbsp; （3） 部署者</font></p>
<img src ="http://www.blogjava.net/J2EEHOME/aggbug/237944.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/J2EEHOME/" target="_blank">J2EE Home工作室</a> 2008-11-01 02:59 <a href="http://www.blogjava.net/J2EEHOME/articles/237944.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>EJB入门文章</title><link>http://www.blogjava.net/J2EEHOME/articles/237943.html</link><dc:creator>J2EE Home工作室</dc:creator><author>J2EE Home工作室</author><pubDate>Fri, 31 Oct 2008 18:58:00 GMT</pubDate><guid>http://www.blogjava.net/J2EEHOME/articles/237943.html</guid><wfw:comment>http://www.blogjava.net/J2EEHOME/comments/237943.html</wfw:comment><comments>http://www.blogjava.net/J2EEHOME/articles/237943.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/J2EEHOME/comments/commentRss/237943.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/J2EEHOME/services/trackbacks/237943.html</trackback:ping><description><![CDATA[<div id="article">
<p><font face="Verdana">一.Enterprise Beans<br />
在EJB（Enterprise Java Beans）中定义了两种不同类别的Enterprise Bean ：<br />
*会话 Bean (Session Bean)<br />
*实体Bean (Entity Bean)</font></p>
<p><font face="Verdana">1. 会话 Bean (Session Bean)<br />
会话 Bean 是调用它的客户端代码要完成的工作。当客户端与服务器建立联系，那么一个会话 Bean 就建立起来了。根据会话 Bean 的状态不同有分为:<br />
A. 状态会话 Bean (Stateful Session Bean)<br />
B. 无状态会话 Bean (Stateless Session Bean)<br />
1.1 状态会话 Bean (Stateful Session Bean)<br />
当客户机和服务器建立连接之后，状态会话 Bean (Stateful Session Bean) 将一直在客户机和服务器之间保持着用户的某个状态。例如：用户使用银行的ATM时，经过验证之后，用户可以连续执行多次操作，在这个过程当中，用户的合法状态将一直被保留，直到她将信用卡取出，结束这次操作。这时，状态会话 Bean (Stateful Session Bean) 也就被销毁。<br />
1.2无状态会话 Bean (Stateless Session Bean)<br />
当客户机和服务器建立连接之后，无状态会话 Bean (Stateless Session Bean)处理单一的用户请求或商务过程。无状态会话 Bean (Stateless Session Bean)不需要从以前的请求中提取任何状态。例如，用户的用户密码确认。用户输入密码后，发送请求。组件返回真或假来确认用户，一旦过程完成，无状态会话 Bean (Stateless Session Bean) 也宣告结束。<br />
2. 实体Bean (Entity Bean)<br />
实体Bean (Entity Bean)只是数据模型，它不包括商务逻辑。实体Bean (Entity Bean)可以将关系/对象数据库的数据映射到内存中供其它组件使用。实体Bean (Entity Bean)是一直存在的，而且具有很高的容错性能。实体Bean (Entity Bean)能供允许多用户同时访问。</font></p>
<p><font face="Verdana">二. 会话 Bean (Session Bean)<br />
Ejb的执行过程是被放在一个EJB容器中进行的，所以客户端不会直接调用我们写好的Enterprise Bean ，而是调用EJB容器生成的一个EJBObject (EJB对象)来实现。那么，我们在编写服务器端的Enterprise Bean 时，就要考虑这点。既然客户端不能直接访问，就由EJBObject来代劳，所以在编写服务器端时，就要编写服务器端的一个接口（Remote）用来与客户机联系，实力化EJBObject。要生成EJBObject 就要调有Home 接口，来建立这个实力。</font></p>
<font face="Verdana">
<p><br />
以下是会话 Bean 的代码分析：<br />
A.Enterprise Bean 类：sailorsy.class<br />
1.setSessionContext(SessionContext ctx)方法<br />
它是EJB容器和Enterprise Bean互相作用的关口。</p>
<p>&nbsp;</p>
<p>&nbsp;import java.rmi.*;import javax.ejb.*;public class sailorsy implements SessionBean{private SessionContext ctx=null;public voic setSessionContext(SessionContext ctx){this.ctx=ctx;}//setSessionContext}//class sailorsy<br />
&nbsp;</p>
<p>2.ejbCreate(&#8230;)方法<br />
它可以初始化Enterprise Bean ,可以定义不同的ejbCreate(&#8230;)方法，每个方法所带的参数不同。但是，必许要存在至少一种。</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp; import java.rmi.*;&nbsp; import javax.ejb.*;public class sailorsy implements SessionBean{private SessionContext ctx=null;public voic setSessionContext(SessionContext ctx){this.ctx=ctx;}//setSessionContext&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public void ejbCreate() {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }//ejbCreate}//class sailorsy<br />
&nbsp;</p>
<p>3.ejbPassivate()方法<br />
如果初始化的Enterprise Bean 过多，EJB容器将其中的一些挂起（passivate）,释放他们所占用的空间。</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp; import java.rmi.*;&nbsp; import javax.ejb.*;public class sailorsy implements SessionBean{private SessionContext ctx=null;public voic setSessionContext(SessionContext ctx){this.ctx=ctx;}//setSessionContext&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public void ejbCreate() {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }//ejbCreate&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public void ejbPassivate() {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }//ejbPassivate}//class sailorsy<br />
&nbsp;</p>
<p>4.ejbActivate()方法<br />
和ejbPassivate正好相反，它将被挂起的Bean从新调回。</p>
<p>&nbsp;</p>
<p>&nbsp;import java.rmi.*;&nbsp; import javax.ejb.*;public class sailorsy implements SessionBean{private SessionContext ctx=null;public voic setSessionContext(SessionContext ctx){this.ctx=ctx;}//setSessionContext&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public void ejbCreate() {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }//ejbCreate&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public void ejbPassivate() {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }//ejbPassivate&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public void ejbActivate() {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }//ejbActivate}//class sailorsy<br />
&nbsp;</p>
<p>5.ejbRemove()方法<br />
它可以清除EJB容器中的Bean。</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp; import java.rmi.*;&nbsp; import javax.ejb.*;public class sailorsy implements SessionBean{private SessionContext ctx=null;public voic setSessionContext(SessionContext ctx){this.ctx=ctx;}//setSessionContext&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public void ejbCreate() {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }//ejbCreate&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public void ejbPassivate() {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }//ejbPassivate&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public void ejbActivate() {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }//ejbActivate&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public void ejbRemove() {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }//ejbRemove&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public String showname(){&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return "Hello,my name is sailorsy";&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }//自己的商务方法}//class sailorsy<br />
&nbsp;</p>
<p>以上这些是EJB必需的回调方法，我们可以在里面加入自己的方法，加入自己的商务逻辑。<br />
B.Home 接口: sailorsyHome</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp; import java.rmi.*;import javax.ejb.*;public interface sailorsyHome extends EJBHome {&nbsp; public sailorsyRemote create() throws RemoteException, CreateException;}C.&nbsp;Remote接口：sailorsyRemoteimport java.rmi.*;import javax.ejb.*;public interface sailorsyRemote extends EJBObject {&nbsp; public java.lang.String showname() throws RemoteException;}<br />
&nbsp;</p>
<p>三.调用会话 Bean：sailorsyTestClient1 </p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; import javax.naming.*;import javax.ejb.*;import javax.rmi.PortableRemoteObject;import java.rmi.*;public class sailorsyTestClient1 {&nbsp; private sailorsyHome sailorsyHomeObject = null;&nbsp; //Construct the EJB test client&nbsp; public sailorsyTestClient1() {&nbsp;&nbsp;&nbsp; try {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //以下是客户端使用JNDI定位Home对象。&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Context ctx = new InitialContext();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //look up jndi name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Object ref = ctx.lookup("sailorsy");&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //cast to Home interface&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sailorsyHomeObject = (sailorsyHome) PortableRemoteObject.narrow(ref, sailorsyHome.class);&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp; catch(Exception e) {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; e.printStackTrace();&nbsp;&nbsp;&nbsp; }&nbsp; }&nbsp; //----------------------------------------------------------------------------&nbsp; // Utility Methods&nbsp; //----------------------------------------------------------------------------&nbsp; public sailorsyHome getHome() {&nbsp;&nbsp;&nbsp; return sailorsyHomeObject;&nbsp; }&nbsp; //Main method&nbsp; public static void main(String[] args) throws Exception{&nbsp;&nbsp;&nbsp; sailorsyTestClient1 client = new sailorsyTestClient1();&nbsp;&nbsp;&nbsp; sailorsyRemote sr=client.getHome() .create() ;&nbsp;&nbsp;&nbsp; String s=sr.showname() ;&nbsp;&nbsp;&nbsp; System.out.print(s);&nbsp;&nbsp;&nbsp; // Use the getHome() method of the client object to call Home interface&nbsp;&nbsp;&nbsp; // methods that will return a Remote interface reference.&nbsp; Then&nbsp;&nbsp;&nbsp; // use that Remote interface reference to access the EJB.&nbsp; }}<br />
&nbsp;</p>
<p>以上的EJB在win2000+jbuilder5/jbuilder6+BAS4.5经过测试。</p>
<p><br />
以下是整个EJB的执行过程：<br />
1. 客户端通过JNDI检索Home对象的引用；<br />
2. JNDI返回Home对象的引用；<br />
3. 请求创建一个新的EJB对象；<br />
4. 创建EJB对象；<br />
5. 返回EJB对象；<br />
6. 调用商务方法；<br />
7. 调用Enterprise Bean.</font></p>
</div>
<img src ="http://www.blogjava.net/J2EEHOME/aggbug/237943.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/J2EEHOME/" target="_blank">J2EE Home工作室</a> 2008-11-01 02:58 <a href="http://www.blogjava.net/J2EEHOME/articles/237943.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>EJB初学者常有的十二个疑惑</title><link>http://www.blogjava.net/J2EEHOME/articles/237942.html</link><dc:creator>J2EE Home工作室</dc:creator><author>J2EE Home工作室</author><pubDate>Fri, 31 Oct 2008 18:56:00 GMT</pubDate><guid>http://www.blogjava.net/J2EEHOME/articles/237942.html</guid><wfw:comment>http://www.blogjava.net/J2EEHOME/comments/237942.html</wfw:comment><comments>http://www.blogjava.net/J2EEHOME/articles/237942.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/J2EEHOME/comments/commentRss/237942.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/J2EEHOME/services/trackbacks/237942.html</trackback:ping><description><![CDATA[<div id="article">
<p><font face="Times New Roman">1、EJB2.0有哪些内容?分别用在什么场合? EJB2.0和EJB1.1的区别?</font></p>
<p><font face="Times New Roman">　　答：规范内容包括Bean提供者，应用程序装配者，EJB容器，EJB配置工具，EJB服务提供者，系统管理员。这里面，EJB容器是EJB之所以能够运行的核心。EJB容器管理着EJB的创建，撤消，激活，去活，与数据库的连接等等重要的核心工作。JSP,Servlet,EJB,JNDI,JDBC,JMS.....</font></p>
<p><font face="Times New Roman">　　2、EJB与JAVA BEAN的区别?</font></p>
<p><font face="Times New Roman">　　答：Java Bean 是可复用的组件，对Java Bean并没有严格的规范，理论上讲，任何一个Java类都可以是一个Bean。但通常情况下，由于Java Bean是被容器所创建(如Tomcat)的，所以Java Bean应具有一个无参的构造器，另外，通常Java Bean还要实现Serializable接口用于实现Bean的持久性。Java Bean实际上相当于微软COM模型中的本地进程内COM组件，它是不能被跨进程访问的。Enterprise Java Bean 相当于DCOM，即分布式组件。它是基于Java的远程方法调用(RMI)技术的，所以EJB可以被远程访问(跨进程、跨计算机)。但EJB必须被布署在诸如Webspere、WebLogic这样的容器中，EJB客户从不直接访问真正的EJB组件，而是通过其容器访问。EJB容器是EJB组件的代理，EJB组件由容器所创建和管理。客户通过容器来访问真正的EJB组件。</font></p>
<p><font face="Times New Roman">　　3、EJB是基于哪些技术实现的?并说出SessionBean和EntityBean的区别，StatefulBean和StatelessBean的区别。</font></p>
<p><font face="Times New Roman">　　答：EJB包括Session Bean、Entity Bean、Message Driven Bean，基于JNDI、RMI、JAT等技术实现。</font></p>
<p><font face="Times New Roman">　　SessionBean在J2EE应用程序中被用来完成一些服务器端的业务操作，例如访问数据库、调用其他EJB组件。EntityBean被用来代表应用系统中用到的数据。</font></p>
<p><font face="Times New Roman">　　对于客户机，SessionBean是一种非持久性对象，它实现某些在服务器上运行的业务逻辑。</font></p>
<p><font face="Times New Roman">　　对于客户机，EntityBean是一种持久性对象，它代表一个存储在持久性存储器中的实体的对象视图，或是一个由现有企业应用程序实现的实体。</font></p>
<p><font face="Times New Roman">　　Session Bean 还可以再细分为 Stateful Session Bean 与 Stateless Session Bean ，这两种的 Session Bean都可以将系统逻辑放在 method之中执行，不同的是 Stateful Session Bean 可以记录呼叫者的状态，因此通常来说，一个使用者会有一个相对应的 Stateful Session Bean 的实体。Stateless Session Bean 虽然也是逻辑组件，但是他却不负责记录使用者状态，也就是说当使用者呼叫 Stateless Session Bean 的时候，EJB Container 并不会找寻特定的 Stateless Session Bean 的实体来执行这个 method。换言之，很可能数个使用者在执行某个 Stateless Session Bean 的 methods 时，会是同一个 Bean 的 Instance 在执行。从内存方面来看， Stateful Session Bean 与 Stateless Session Bean 比较， Stateful Session Bean 会消耗 J2EE Server 较多的内存，然而 Stateful Session Bean 的优势却在于他可以维持使用者的状态。</font></p>
<p><font face="Times New Roman">　　4、EJB与JAVA BEAN的区别?</font></p>
<p><font face="Times New Roman">　　答：Java Bean 是可复用的组件，对Java Bean并没有严格的规范，理论上讲，任何一个Java类都可以是一个Bean。但通常情况下，由于Java Bean是被容器所创建(如Tomcat)的，所以Java Bean应具有一个无参的构造器，另外，通常Java Bean还要实现Serializable接口用于实现Bean的持久性。Java Bean实际上相当于微软COM模型中的本地进程内COM组件，它是不能被跨进程访问的。Enterprise Java Bean 相当于DCOM，即分布式组件。它是基于Java的远程方法调用(RMI)技术的，所以EJB可以被远程访问(跨进程、跨计算机)。但EJB必须被布署在诸如Webspere、WebLogic这样的容器中，EJB客户从不直接访问真正的EJB组件，而是通过其容器访问。EJB容器是EJB组件的代理，EJB组件由容器所创建和管理。客户通过容器来访问真正的EJB组件。</font></p>
<p><font face="Times New Roman">　　EJB包括(SessionBean,EntityBean)说出他们的生命周期，及如何管理事务的?</font></p>
<p><font face="Times New Roman">　　SessionBean：Stateless Session Bean 的生命周期是由容器决定的，当客户机发出请求要建立一个Bean的实例时，EJB容器不一定要创建一个新的Bean的实例供客户机调用，而是随便找一个现有的实例提供给客户机。当客户机第一次调用一个Stateful Session Bean 时，容器必须立即在服务器中创建一个新的Bean实例，并关联到客户机上，以后此客户机调用Stateful Session Bean 的方法时容器会把调用分派到与此客户机相关联的Bean实例。</font></p>
<p><font face="Times New Roman">　　EntityBean：Entity Beans能存活相对较长的时间，并且状态是持续的。只要数据库中的数据存在，Entity beans就一直存活。而不是按照应用程序或者服务进程来说的。即使EJB容器崩溃了，Entity beans也是存活的。Entity Beans生命周期能够被容器或者 Beans自己管理。</font></p>
<p><font face="Times New Roman">　　EJB通过以下技术管理实务：对象管理组织(OMG)的对象实务服务(OTS)，Sun Microsystems的Transaction Service(JTS)、Java Transaction API(JTA)，开发组(X/Open)的XA接口。</font></p>
<p><font face="Times New Roman">　　5、EJB的角色和三个对象</font></p>
<p><font face="Times New Roman">　　答：一个完整的基于EJB的分布式计算结构由六个角色组成，这六个角色可以由不同的开发商提供，每个角色所作的工作必须遵循Sun公司提供的EJB规范，以保证彼此之间的兼容性。这六个角色分别是EJB组件开发者(Enterprise Bean Provider) 、应用组合者(Application Assembler)、部署者(Deployer)、EJB 服务器提供者(EJB Server Provider)、EJB 容器提供者(EJB Container Provider)、系统管理员(System Administrator)</font></p>
<p><font face="Times New Roman">　　三个对象是Remote(Local)接口、Home(LocalHome)接口，Bean类</font></p>
<p><font face="Times New Roman">&nbsp;&nbsp;&nbsp; 6、EJB容器提供的服务</font></p>
<p><font face="Times New Roman">　　答：主要提供声明周期管理、代码产生、持续性管理、安全、事务管理、锁和并发行管理等服务。</font></p>
<p><font face="Times New Roman">　　7、EJB规范规定EJB中禁止的操作有哪些?</font></p>
<p><font face="Times New Roman">　　答：1.不能操作线程和线程API(线程API指非线程对象的方法如notify,wait等)，2.不能操作awt，3.不能实现服务器功能，4.不能对静态属生存取，5.不能使用IO操作直接存取文件系统，6.不能加载本地库.，7.不能将this作为变量和返回，8.不能循环调用。</font></p>
<p><font face="Times New Roman">　　8、remote接口和home接口主要作用</font></p>
<p><font face="Times New Roman">　　答：remote接口定义了业务方法，用于EJB客户端调用业务方法。</font></p>
<p><font face="Times New Roman">　　home接口是EJB工厂用于创建和移除查找EJB实例</font></p>
<p><font face="Times New Roman">　　9、bean 实例的生命周期</font></p>
<p><font face="Times New Roman">　　答：对于Stateless Session Bean、Entity Bean、Message Driven Bean一般存在缓冲池管理，而对于Entity Bean和Statefull Session Bean存在Cache管理，通常包含创建实例，设置上下文、创建EJB Object(create)、业务方法调用、remove等过程，对于存在缓冲池管理的Bean，在create之后实例并不从内存清除，而是采用缓冲池调度机制不断重用实例，而对于存在Cache管理的Bean则通过激活和去激活机制保持Bean的状态并限制内存中实例数量。</font></p>
<p><font face="Times New Roman">　　10、EJB的激活机制</font></p>
<p><font face="Times New Roman">　　答：以Stateful Session Bean 为例：其Cache大小决定了内存中可以同时存在的Bean实例的数量，根据MRU或NRU算法，实例在激活和去激活状态之间迁移，激活机制是当客户端调用某个EJB实例业务方法时，如果对应EJB Object发现自己没有绑定对应的Bean实例则从其去激活Bean存储中(通过序列化机制存储实例)回复(激活)此实例。状态变迁前会调用对应的ejbActive和ejbPassivate方法。</font></p>
<p><font face="Times New Roman">　　11、EJB的几种类型</font></p>
<p><font face="Times New Roman">　　答：会话(Session)Bean ，实体(Entity)Bean 消息驱动的(Message Driven)Bean</font></p>
<p><font face="Times New Roman">　　会话Bean又可分为有状态(Stateful)和无状态(Stateless)两种</font></p>
<p><font face="Times New Roman">　　实体Bean可分为Bean管理的持续性(BMP)和容器管理的持续性(CMP)两种</font></p>
<p><font face="Times New Roman">　　12、客服端调用EJB对象的几个基本步骤</font></p>
<p><font face="Times New Roman">　　答：设置JNDI服务工厂以及JNDI服务地址系统属性，查找Home接口，从Home接口调用Create方法创建Remote接口，通过Remote接口调用其业务方法。</font></p>
</div>
<img src ="http://www.blogjava.net/J2EEHOME/aggbug/237942.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/J2EEHOME/" target="_blank">J2EE Home工作室</a> 2008-11-01 02:56 <a href="http://www.blogjava.net/J2EEHOME/articles/237942.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>