??xml version="1.0" encoding="utf-8" standalone="yes"?>jizz在线观看,亚洲欧美日本在线,婷婷六月国产精品久久不卡http://www2.blogjava.net/kapok/category/891.html垃圾?嘿嘿Q我藏的q么׃们还能找到啊Q真牛!zh-cnWed, 28 Feb 2007 03:24:36 GMTWed, 28 Feb 2007 03:24:36 GMT60Lq行Java Portlets 开发基于JSR 168的开发和部v http://www.aygfsteel.com/kapok/archive/2005/04/22/3630.htmlW笨W笨Fri, 22 Apr 2005 13:55:00 GMThttp://www.aygfsteel.com/kapok/archive/2005/04/22/3630.htmlhttp://www.aygfsteel.com/kapok/comments/3630.htmlhttp://www.aygfsteel.com/kapok/archive/2005/04/22/3630.html#Feedback0http://www.aygfsteel.com/kapok/comments/commentRss/3630.htmlhttp://www.aygfsteel.com/kapok/services/trackbacks/3630.htmlhttp://dev2dev.bea.com.cn/techdoc/webplat/200410224.html

 摘要
  Portlet是生成片D(遵守特定规范的标记语aQ如HTML、XMLQ的片段Q的Weblg。片D再合成一个完整的文档。本文介l了关于Java Portlet的Java Specification Request (JSR) 168规范。它说明了如何用BEA WebLogic Workshop 8.1 SP2来创建Java PortletQ以及如何将q些portlet部v到BEA WebLogic Portal 8.1 Sp2上。我介l一些关键概念,如门戗桌面和portletQƈ详细描述多种portlet模式和窗口状态。我q将介绍如何使用Workshop来设计、实现、配|和执行portlet?BR>

  JSR 168定义了有关Java Portlet的规范。门h一个Web应用E序和一个portlet的聚合。Portlet容器q行portletQƈ理它们的生命周期。JSR 168定义了portlet与portlet容器之间的契U,它没有定义portlet容器与门户之间的契约。门L实现留给了门户供应商?BR>
  BEA WebLogic门户
  BEA WebLogic Portal (8.1 SP2)的当前版本支持不同类型的portletQJSP/HTML portlet、Java PageFlow portlet、Struts portlet和Java portletQ将来还会支持其他portletQ如Web Services for Remote Portlets (WSRP)。我们将着重介lJava portlet?BR>
  WebLogic Portal提供了JSR 168中未描述的门户功能,包括但不限于Q书和页面中portlet的组l、多渠道支持和用skin、skeleton和shell定制?BR>
  Z能够l箋下去Q在q行下一部分之前Q请先完成以下内容:
   ·使用WebLogic Domain Configuration Wizard创徏一个门户域Q如JSR168PortalDomainQ?
   ·使用WebLogic Workshop创徏一个用上面所建立域的门户应用E序Q如JSR168PortalAppQ?
   ·在门户应用程序内创徏一个门户Web目Q如JSR168PortalWebProjectQ?
   ·在门户Web目中创Z个WebLogic Portal .portal文gQ如JSR168.portalQ?
   ·启动服务器实例?

  创徏您的W一个Java Portlet
  下面的步骤描qC如何创徏您的W一个JSR 168 portlet?BR>  ·在门户Web目Q如JSR168PortalWebProjectQ中Q用WebLogic Workshop为portletQ入FirstPortletQ创Z个新文g夏V?
  ·在新文g夹内使用Wizard通过创徏相应?portlet文g创徏一个新portletQ如FirstportletQ?BR>  ·选择portletcd为Java Portlet?
  ·指定标题Q如FirstQ?
  ·指定定义标签Q如firstQ?BR>  ·指定cdUͼ如com.malani.examples.portlets.jsr168.FirstPortletQ?
  ·打开门户Q如JSR168.portalQ?
  ·portletQ如FirstportletQ拖攑ֈ门户中的面上(如JSR168.portalQ?
  ·q行.portal文gq行试?

  您的W一个JSR 168 portlet已经成功q行了!但向导在背后作了些什么呢Q?BR>  ·它创Z一个特定于WebLogic Workshop和WebLogic Portal?portlet文g?portlet文g构成了与特定于Workshop和WebLogic Portal?portal文g的契U?
  ·向导创徏了一?java文gQ如com.malani.examples.portlets.jsr168.FirstPortlet.javaQ,该文件放|在WEB-INF/src目录中?BR>  ·向导创徏了一个WEB-INF/portlet.xml配置文gQƈ为portlet在文件中插入了一个条目。该portlet的条目看上去如下Q?BR>
<portlet>
<description>Description goes here</description>
<portlet-name>first</portlet-name>
<portlet-class>com.malani.examples.portlets.jsr168.FirstPortlet
</portlet-class>
<portlet-info>
<title>First</title>
</portlet-info>
</portlet>


  Java Portletc?/B>
  在该CZ中,向导生成的Portlet Java文g扩展了javax.portlet.GenericPortletcRGenericPortletcdCjavax.portlet.Portlet接口。图1是一个Unified Modeling Language (UML)cdQ描qCq些关系。通过直接实现portlet接口Q可以编写一个portlet。然而,GenericPortlet是一个创建portlet的更方便Ҏ。首先,我们看一下portlet生命周期、portlet模式和window状态?


?1

  Portlet生命周期
  Z成功地创建portletQ您必须늅portlet生命周期。javax.portlet.Portlet接口中的Ҏ定义了该生命周期Q这些生命周期方法是init()、render()、processAction()和destroy()。当部vportlet的实例时调用init()Ҏ。它用于获得所需的Q何昂贵资源(如后台连接)Qƈ执行其他一ơ性活动。当portlet的实例被撤销部vӞ使用destroy()Ҏ来释放这些资源?BR>
  Portlet规范清晰区别renderh和动作请求。图2描述了portleth和响应的一个UMLcd。门户页面上的renderh会导致对所面上的每个portlet上调用render()ҎQ当用户在特定portlet上调用某个动作(通常是HTML表单提交Q时Q将会调用该portlet的processAction()Ҏ。这P用户的动作请求{换ؓprocessAction()Ҏ的一ơ调用和render()Ҏ的多ơ调用?/P>


?2

  ?是一个序列图Q说明了调用processAction()Ҏ的效果,以及为同一面上的portletq行后箋render()Ҏ的调用。关于更多信息,请参阅关于处理动作的一节?/P>


?3

  有两U重载的init()ҎQ一个没有参敎ͼ另一个有一个javax.portlet.PortletConfigcȝ实例。注意:关于init(PortletConfig)有一个特D的caveat。调用super.init(aPortletConfig)p|导致一个NullPointerException。所包含的源代码CZ中的Init portlet说明了这U行为(源代码可以在www.sys-con.com/weblogic/source.cfm中找刎ͼ?BR>
  Portlet模式
  JSR 168定义了三UPortlet模式QVIEW、EDIT和HELP。一个portlet实例在Q何时候都可以恰y在一U portlet模式下。其他自定义portlet模式Q如配置和源Q都是可能的。VIEW模式是默认的模式。Portlet规范EDIT模式允许portlet用户定制portlet实例Q以及HELP模式昄关于portlet的用法信息。Portlet必须支持VIEW模式Q但在portlet中对EDIT模式和HELP模式的支持是可选的。例如,portlet First portletCZ不支持EDIT模式和HELP模式?BR>
  window状?/B>
  JSR 168定义了三UWindow状态:NORMAL、MINIMIZED和MAXIMIZED。Portlet实例M时候都可以恰好是一Uwindow状态。其他自定义window状态(如半)也是可能的。在NORMAL状态下Qportlet占了屏幕区的一部分。屏q状态与其他portlet׃n。在MINIMIZED状态下Qportlet的内容被隐藏。在MAXIMIZED状态下Qportlet的内容占屏幕区的大部分。其他共享同一面的portlet在MAXIMIZED状态下被隐藏。例如,portlet FirstCZ支持所有三Uwindow状态?BR>
  GenericPortletc?/B>
  您创建的大多数portlet会扩展javax.portlet.GenericPortletc,而不是直接实现javax.portlet.Portlet接口。GenericPortletcdCrender()Ҏ。如果portlet的window状态被最化Q那么render()Ҏ不能做Q何事情。如果portlet的window状态不是最化Q那么render()Ҏ讄在portlet.xml文g中指定的标题Qƈ调用doDispatch()Ҏ。根据Portlet模式Q?doDispatch()Ҏ适当地调用doView()、doEdit()和doHelp()Ҏ。这P׃GenericPortletcd助实现render()ҎQƈ且提供doView()、doEdit()和doHelp()Ҏ来覆盖,因此GenericPortletcLPortlet接口更便于扩展?

  考虑一下First portletCZ。FirstPortletcL展了GenericPortletQFirstPortlet改写了doView()Ҏ?BR>
public void doView(RenderRequest request, RenderResponse response)
throws PortletException, IOException
{
response.setContentType("text/html");
response.getWriter().write("<p>Hello World</p>");
}


  注意Q调用setContentType()Ҏ前调用getWriter()Ҏ会导致java.lang.IllegalStateException?BR>
  实现Portlet模式
  VIEW模式是强制的Q但EDIT和HELP模式是可选的。ؓ了实现EDIT和HELP portlet模式Q需要在portletcM实现适当的doEdit()和doHelp()Ҏ。请参考包含在源代码示例(本文的源代码可以在www.sys-con.com/wldj/sourcec.cfm扑ֈQ中的portlet Mode。此外,必须在portlet.xml中如下配|各模式Q?BR>
<supports>
<mime-type>text/html</mime-type>
<portlet-mode>edit</portlet-mode>
<portlet-mode>help</portlet-mode>
</supports>


  注意Q修改portlet.xml配置文gQ但不实现portletcM的相应方法,会导致javax.portlet.PortletException?BR>
  实现window状?/B>
  JSR 168没有描述用window状态支持的Ҏ。然而,WebLogic Portal实现了对它们的禁用。ؓ了禁用portlet对window状态的支持Q需要在weblogic-portlet.xml文g中排除window状态:

<portlet>
<portlet-name>state</portlet-name>
<supports>
<mime-type>text/html</mime-type>
<excluded-window-state>minimized</excluded-window-state>
<excluded-window-state>maximized</excluded-window-state>
</supports>
</portlet>


  请参考源代码CZ中的portlet State?BR>
  包含JavaServer Pages (JSPs)
  考虑portlet First的doView()ҎQ该Ҏ获得了Writer的实例,q直接输出HTML片段。由于多U原因(如ؓ了达到Java逻辑与HTML视图表现的分)Q往往不推荐输出直接的HTML片段。推荐的Ҏ是用JSP来显C图。portletcM的方法执行业务逻辑、设|render参数以及包含JSP。ؓ了包含一个特定的JSPQ应首先获得PortletContext。从PortletContext实例中,通过调用getRequestDispatcher()Ҏ获得一个PortletRequestDispatcher的实例。通过调用include()Ҏ来包含JSP。例如:

// execute the necessary logic here...
PortletRequestDispatcher aDispatcher =
getPortletContext().getRequestDispatcher(
"/IncludePortlet/includeView.jsp"
);
aDispatcher.include(aRequest, aResponse);


  注意Q在执行render()ҎӞportlet可能只用一个PortletRequestDispatcher对象?BR>  请参考包含在源代码中的portlet Include。JSP面Q如includeView.jspQ不包含根HTML标签Q如<html>?lt;title>?lt;body>Q,因ؓq些标签由门h架提供。JSP面只包含显Cportlet所必需的HTML片段?BR>
  处理动作
  在一个标准的Web应用E序中,一个HTML表单提交导致执行一些业务逻辑。业务处理的l果Q要么作为属性而被讄在请求或会话中ƈ转发Q要么包含到下一个JSP?BR>
  在一个JSR 168 portlet中,一个HTML表单的动作URL应该是什么样呢?JSR 168定义了一个JSP标签库,UCؓportlet taglib。HTML表单的动作URL可以使用actionURL portlet标签生成。例如(请参考favoriteColorEdit.jsp文gQ:

<form action="<portlet:actionURL/>" method="post">
...
</form>


  提交该HTML表单会D调用portlet的processAction(ActionRequest aRequest, ActionResponse aResponse)Ҏ。像通常一P可以通过调用request对象的getParameter()Ҏ来获得表单参数。注意:通过提交表单调用动作Q但portlet中却没有processAction()ҎQ将会导致javax.portlet.PortletException?BR>
  processAction()Ҏ讄response对象中的倹{不要用ActionRequest或ActionResponse对象的setAttribute()Ҏ。g会从processAction()传递到render()ҎQ而且在JSP中是不可用的。相反要使用ActionResponse对象的setRenderParameter()Ҏ。这些render参数对所有后lrenderh可用Q这一点与典型的Web应用E序h属性很不相同。典型的Web applicationh属性只对于一个请求可用。另一斚wQrenderh参数对于许多后箋renderh可用。render参数保持可用直到D动作的重新执行显式地修改或删除?BR>
  考虑portlet FavoriteColor。它在VIEW模式昄了一个用户偏好的颜色Q但是可以在EDIT模式下更攏V在EDIT模式下提交偏好的颜色选择调用processAction()Ҏ。该Ҏ获得偏好的颜色请求参敎ͼq将其设|ؓrender参数。这P偏好的的颜色render参数在所有后lrenderh中都可用?BR>
  所呈现的参数是怎样昄在JSP上的呢?应用来自portlet标签库的defineObjects标签来定义portlet对象。该标签使renderRequest、renderResponse和portletConfig portlet对象在页面中可用。参数通过调用renderRequest对象的getParameter()Ҏ来显C。请参考与所包含的源代码CZ中的favoriteColorView.jsp?BR>
  portlet FavoriteColor也展CZ其他概念。第一个是如何在processAction()Ҏ中用~程的方法改变portlet模式。调用ActionResponse对象的setPortletMode()Ҏ来修改portlet模式。第二个概念是如何用一个HTML链接来修改portlet模式。该链接使用来自portlet标签库的renderURL标签生成。根据希望的portlet模式指定portletMode属性的倹{请参考源代码CZ中的FavoriteColorPortletcdfavoriteColorView.jsp面?

  Portlet Preferences
  Portlet PreferencesQPortlet首选项Q是portlet的基本配|数据。一个preference是一个“名U和值”对。名U的cd是一个字W串Q而值的cd是字W串或字W串数组。Portlet Preference不适于存储L数据。portlet容器为portlet preferences提供持久性。在WebLogic Portal中,preference的持久性只在下面两个条仉为真时才起作用:
  ·门户q行在桌面中Q而不是DOT门户模式?BR>  ·用户已经d?BR>
  桌面与DOT门户模式
  在WebLogic Workshop中创?portal文gӞ像书、页面和portlet{项都可以被拖放?portal文g中,.portal文g能够直接从Workshop内运行。然而,某些功能Q如preferences的存储,在这UDOT门户模式下运行时是不可用的(DOT门户模式也称为单文g模式QSingle File ModeQ)?

  其他模式UCؓ桌面模式。创Z个门h使用Portal Administrator。在门户内,一个桌面被创徏。像图书、页面和portlet{项被创建,q放|在桌面中。在q种模式下,某些功能Q像preferences的存储,是可用的Q桌面模式也被称为流模式QStreamed ModeQ)?BR>
在l讨论前Q先创徏一个桌面:
  启动Portal AdministrationQ譬如,http://localhost:7001/JSR168PortalAppAdmin/Q。一U启动Portal Administration的方法是直接从Workshop中启动。选择Portal菜单Q选中Portal Administration菜单V?
  ·dqPortal Administration?BR>  ·创徏一个新门户Q譬如,JSR168Q?
  ·在门户中Q创Z个新桌面Q如d1Q?
  ·LoginPortletd到桌面的一个页面中?
  ·ContactPortletd到桌面的一个文件中?

  Portlet PreferencesCZ
  Contact portlet演示了Portlet Preferences。Portlet Preferences可以是静态的或动态的。静?preferences与portlet一起在portal.xml文g中指定。例如,ContactPortleth一个成为contact-preference?preferences。contact-preference的默认g被指定:

<portlet-preferences>
<preference>
<name>contact-preference</name>
<value>Email</value>
</preference>
</portlet-preferences>


  动?preferences不在portlet.xml配置文g中预定义。当portletq行Ӟq些preferences被存储和d。在q行期间Q一个javax.portlet.PortletPreferences接口的实例包含这些preferences。该实例通过调用PortletRequest对象的getPreferences()Ҏ获得。特定preferences的值通过调用preferences实例上的getValue()Ҏ来获得?

  调用preferences实例的setValue()Ҏ会更C个preferences倹{然而,需要一个额外的步骤来提交这些修攏Vpreferences实例的store()Ҏ被调用来使preferences持久化。preferences只能在processAction()Ҏ中进行修攏V如果在processAction()Ҏ中没有调用store()ҎQQ何对preferences实例的修攚w会被丢弃。注意:如前面提到的,如果用户没有d或门户处于DOT门户模式Q那么调用store()Ҏ会D一个运行时异常?BR>
  在portlet和servlet之间有很多相似点。然而,它们也存在着重要区别。portlet规范建立在servlet规范之上。portlet容器存在于servlet容器中。就像servlet部v在一个Web应用E序中,portlet也是如此。Servlet和Web应用E序使用portlet.xml文gq行配置。一个servleth昑ּ的生命周期:init()、doGet()、doPost(){。类似地Q一个portlet也具有显式的生命周期QdoView()、doEdit()、processAction(){。servlet和portletcȝҎ必须以安全线E的方式~码?BR>
  然而,也存在着重要的区别。Servlet被允许进行include、forward和redirect操作Q然而portlet只被允许q行include操作。Servlet能够呈现一个完整的面Q但portlet只提交页面片Dcportleth严格定义的portlet模式和Window状态,q方面不像servlet。Portleth更正式的hQ对renderh和动作请求进行处理,它们也具有preferences。portletq不是servletQ?BR>
  l束?/B>
  本文通过使用一个简单的向导描述portlet的创开始,q说明了portlet的生命周期以及portletcd现的内部工作方式Q描qCportlet.xml配置文g和相应的weblogic-portlet.xml配置文g的结构和语义。对各种概念Q如portlet模式和window状态,本文也进行了解释。本文演CZportlet标签库的用法和portlet中的表单处理。最后,我介l了如何使用portletpreferences。理解了本文所介绍的这些知识和概念Q您可以在创徏和部|自q强大portlet的道路上前进了?BR>
  致谢
  感谢Subbu Allamaraju、Max Cooper、Steve Ditlinger、David Lu、Roshni Malani和Alex ToussaintQ他们仔l阅Mq篇文章Qƈ提供了有价值的反馈意见?BR>
  参考资?/B>
  · 要讨文章、ƈ提问问题Q从q里开始: www.bartssandbox.com。需要免Ҏ员资根{?
  · 下蝲、阅读JSR 168Q?A target=_blank>www.jcp.org/en/jsr/detail?id=168
  · WebLogic Portal文档的v始点Q?A target=_blank>e-docs.bea.com/wlp/docs81/index.html
  · 建立Workshop Help的Java Portlet部分Q?A target=_blank>e-docs.bea.com/workshop/docs81/doc/en/core/index.html
  · 用WebLogic Portal 8.1开发JSR 168 PortletQ?A target=_blank>dev2dev.bea.com/products/wlportal81/articles/JSR168.jsp
  · Web Services for Remote Portlets (WSRP)规范Q?A target=_blank>www.oasis-open.org/committees/tc_home.php?wg_abbrev=wsrp
  · 试一下WSRPQ?A target=_blank>dev2dev.bea.com/codelibrary/code/wsrp_supportkit.jsp
  · Single File Mode和Streamed Rendering ModeQ?A target=_blank>单击q里Q?BR>  · 有关Portlet规范上的文章Q?BR>- 介绍Portlet规范Q第1部分Q?BR>www.javaworld.com/javaworld/jw-08-2003/jw-0801-portlet_p.html
-介绍Portlet规范Q第2部分Q?BR>www.javaworld.com/javaworld/jw-09-2003/jw-0905-portlet2_p.html
  · 对JSR 168白皮书的介绍Q单击这里!
  · Java Passion Portlet演讲W记Q?A target=_blank>www.javapassion.com/j2eeadvanced/Portlet4.pdf

  关于作?/B>
  Prakash Malani在架构、设计和开发面向对象的软g斚whq泛的经验,曄在很多应用领域从事过软g开发,如娱乐、零售、机械、通信和互动电视等。他实践和指导着很多领先的技术,如J2EE、UML和XML。   Prakash已经在多个行业领先的出版物上发表了多文章。(更多内容Q?BR>
  源代?/B>
  源代?Zip文g
  英文原文Q?A target=_blank>http://www.sys-con.com/story/?storyid=45565&DE=1



W笨 2005-04-22 21:55 发表评论
]]>
灰狐上面关于JBoss的连?/title><link>http://www.aygfsteel.com/kapok/archive/2005/03/30/2615.html</link><dc:creator>W笨</dc:creator><author>W笨</author><pubDate>Wed, 30 Mar 2005 09:28:00 GMT</pubDate><guid>http://www.aygfsteel.com/kapok/archive/2005/03/30/2615.html</guid><wfw:comment>http://www.aygfsteel.com/kapok/comments/2615.html</wfw:comment><comments>http://www.aygfsteel.com/kapok/archive/2005/03/30/2615.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/kapok/comments/commentRss/2615.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/kapok/services/trackbacks/2615.html</trackback:ping><description><![CDATA[<A >http://www.huihoo.org/jboss/</A><img src ="http://www.aygfsteel.com/kapok/aggbug/2615.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/kapok/" target="_blank">W笨</a> 2005-03-30 17:28 <a href="http://www.aygfsteel.com/kapok/archive/2005/03/30/2615.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JBoss3.0 下配|和部vEJB?/title><link>http://www.aygfsteel.com/kapok/archive/2005/03/30/2614.html</link><dc:creator>W笨</dc:creator><author>W笨</author><pubDate>Wed, 30 Mar 2005 09:19:00 GMT</pubDate><guid>http://www.aygfsteel.com/kapok/archive/2005/03/30/2614.html</guid><wfw:comment>http://www.aygfsteel.com/kapok/comments/2614.html</wfw:comment><comments>http://www.aygfsteel.com/kapok/archive/2005/03/30/2614.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/kapok/comments/commentRss/2614.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/kapok/services/trackbacks/2614.html</trackback:ping><description><![CDATA[     摘要: (by huihoo.org 赉|?zhaochenxi@vip.sina.com) http://www.huihoo.org/jboss/jboss3_ejb.htm 1QJBoss?JBoss是一个运行EJB的J2EE应用服务器。它是开放源代码的项目,遵@最新的J2EE规范。从JBoss目开始至今,它已l从一个EJB容器发展成ؓ一个基于的J2EE的一个web 操作pȝQoper...  <a href='http://www.aygfsteel.com/kapok/archive/2005/03/30/2614.html'>阅读全文</a><img src ="http://www.aygfsteel.com/kapok/aggbug/2614.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/kapok/" target="_blank">W笨</a> 2005-03-30 17:19 <a href="http://www.aygfsteel.com/kapok/archive/2005/03/30/2614.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Jboss 源码解析http://www.aygfsteel.com/kapok/archive/2005/03/29/2569.htmlW笨W笨Tue, 29 Mar 2005 01:46:00 GMThttp://www.aygfsteel.com/kapok/archive/2005/03/29/2569.htmlhttp://www.aygfsteel.com/kapok/comments/2569.htmlhttp://www.aygfsteel.com/kapok/archive/2005/03/29/2569.html#Feedback0http://www.aygfsteel.com/kapok/comments/commentRss/2569.htmlhttp://www.aygfsteel.com/kapok/services/trackbacks/2569.htmlhttp://blog.csdn.net/stripbolt/archive/2004/10/24/149705.aspx

JBoss是一个非怼U的J2EE的Application Server,研究
它的源代码有助于我们更好的理解J2EE的各U技术?
本系列拟从四个方面分析Jboss源码Q?
1.EJB Container实现
2.Transaction实现
3.Persistence Mapping
4.Client到Server端的Invocation

-------------------------------------------------------------------
先说W??EJB Container实现?
1.1 EJB Pool
我们知道QEJB Container 会维护一个EJB池,
在多个client间共享,避免频繁创徏销毁对象的开销?
让我们来看看Jboss实现的Pool:
EJB分EntityBean,MDB,Stateless/Stateful Session Bean,
而Jboss中也对应的有EntityInstancePoolQMessageDrivenInstancePool,
StatefulSessionInstancePool,StatelessSessionInstancePool.
让我们先从这4个类的共同基cAbstractInstancePool看vQ?
class AbstractInstancePool实现了接口InstancePoolQ该接口有以下几个方法:
EnterpriseContext get() throws Exception;
void free(EnterpriseContext ctx);
void discard(EnterpriseContext ctx);
int getCurrentSize();
public int getMaxSize();
--------------------------------------------------------------------
先对EnterpriseContext作番说明。EnterpriseContext的作?
是把具体的EJB instance和它的metadata联系h?
该类{֐为:
public abstract class EnterpriseContextQ?
?个子c,EntityEnterpriseContextQMessageDrivenEnterpriseContextQ?
StatefulSessionEnterpriseContextQStatelessSessionEnterpriseContext?
分别对应4U类型的EJB?
EnterpriseContext中有几个重要的成员变量?
/** The EJB instance */
Object instance;
/** The container using this context */
Container con; //Containerq个cLJBoss用来代表对EJB提供Transaction,SecurityQPool{服务的c,我们回头q会再说?
/** Only StatelessSession beans have no Id, stateful and entity do */
Object id;

/** The transaction associated with the instance */
Transaction transaction; //TransactionQ我们下节再?

// Constructors --------------------------------------------------

public EnterpriseContext(Object instance, Container con)
{
this.instance = instance;
this.con = con;
}

public Object getInstance()
{
return instance;
}
public Container getContainer() {
return con;
}

public void setId(Object id) {
this.id = id;
}

public Object getId() {
return id;
}

public void setTransaction(Transaction transaction) {
this.transaction = transaction;
}

public Transaction getTransaction() {
return transaction;
}

/**
* Get the EJBContext object
*/
public abstract EJBContext getEJBContext(); //由子cd?

//q回javax.ejb.EJBContextQ注意这个EJBContext?
EJB规范要求提供lEJB的Context,与JBoss自己实现cEnterpriseContext没有关系?

/** The instance is being used. This locks it\'s state */
int locked = 0;
public void lock()
{
locked ++;
}

public void unlock() {
locked --;
}

public boolean isLocked() {
return locked != 0;
}
//lockq个成员变量表示当前q个EJB instance有没人在用?
//q个变量用来lReentrance,以及canPassviate?
/**
* before reusing this context we clear it of previous state called
* by pool.free()
* 从pool里取出来的时候没有关联Q何EJB instance和Transaction信息
* 在返qpool的时候把q些信息清掉?
*/
public void clear() {
this.id = null;
this.locked = 0;
this.transaction = null;
}
//-------------------------------------------------------------------------------------
protected boolean isContainerManagedTx()
{
BeanMetaData md = (BeanMetaData)con.getBeanMetaData();
return md.isContainerManagedTx();
}
//从关联的container拿出对应的metadata,判断是否CMT.
//注意q里con是Container成员变量Q可不是什么连接,q接一般羃写ؓconn,
//我一开始就搞؜?)
//BeanMetaDataq些MetaData的子c都是从xml配置里头d来的Metadata构造的,
//没什么神U的.
q个c里头还有两个inner class,EJBContextImpl implements EJBContext,
UserTransactionImpl implements UserTransaction。EJBContextImpl{?
讲解qContainer再说QUserTransaction{下节再说?

现在让我们来看看EnterpriseContext的几个子c:
首先cL一下几个子cȝ成员变量Q?
EntityEnterpriseContextQ?
private EJBObject ejbObject;
private EJBLocalObject ejbLocalObject;
private EntityContext ctx;

StatefulSessionEnterpriseContext
private EJBObject ejbObject;
private EJBLocalObject ejbLocalObject;
private SessionContext ctx;

StatelessSessionEnterpriseContext
EJBObject ejbObject;
EJBLocalObject ejbLocalObject;
SessionContext ctx;

MessageDrivenEnterpriseContextQ?
private MessageDrivenContext ctx;
看来除了MDB没有对应的EJBObject/EJBLocalObject,其他l统都有Q)
学过EJB的h都知道,在语法上EJB instance 是implements
EntityBean/SessionBean/MessageDrivenBean (q?个interface有一个共同的
interface: public interface EnterpriseBean extends Serializable,
EnterpriseBean 是个Marker接口,里头什么都没有Q好像Serializable接口一P只说?
实现它的是个EJB.而EntityBean/SessionBean/MessageDrivenBean 有对应的
void ejbActivate() throws EJBException, RemoteException;
void ejbLoad() throws EJBException, RemoteException;
一些方法需要实现。(虽然常常是空实现Q)Q由容器作了很多?
至于EJBObject/EJBLocalObject 在语法上都是非直接实现的Q代表EJB instance暴露出的Remote/Local 接口。既然这些EJB instance非直接实现这些接口,那么q些接口如何与具体的EJB instance相关联,我们讲到ContainercLq道了?
----------------------------------------------------------------------------------


EnterpriseContext的子cEntityEnterpriseContext的构造函?BR>public EntityEnterpriseContext(Object instance, Container con)
throws RemoteException
{
super(instance, con);
ctx = new EntityContextImpl(); //q是EJBContextImpl的子c,不急着?)
((EntityBean)instance).setEntityContext(ctx);//看看Q原来set...Context是在q里调用?/其它instance实现的什么ejbCreate(),EJBLoad,EJBActive()到底是什么时?
调用的呢Q接下来我们慢慢找,q可散布在各地呢Q)
}
//其他几个子类的构造函数前3行也都如此,是类似的?
对于StatelessSessionEnterpriseContext和MessageDrivenEnterpriseContext,紧接的是

Method ejbCreate = instance.getClass().getMethod(\"ejbCreate\", new Class[0]);
ejbCreate.invoke(instance, new Object[0]);
//看看Q来了一个ejbCreate:),对于StatelessSessionBeanQ一上来ejbCreate()了~
接下来看点简单的Q对于EnterpriseContext,
有public abstract void discard() throws RemoteException;
对于MessageDriven...?
public void discard() throws RemoteException
{
((MessageDrivenBean)instance).ejbRemove();
}
对于StatelessSession?
public void discard() throws RemoteException
{
((SessionBean)instance).ejbRemove();
}
对于StatefulSession...?
public void discard() throws RemoteException
{
// Do nothing
}
对于Entity....
public void discard() throws RemoteException
{
((EntityBean)instance).unsetEntityContext();
}
//discard 是在AbstractInstancePool中的
void discard(EnterpriseContext ctx);调用?

/**
* Discard an anonymous instance after invocation.
* This is called if the instance should not be reused, perhaps due to some
* exception being thrown from it.
*
* @param ctx The context to discard.
*/
public void discard(EnterpriseContext ctx)
{
ctx.discard();
}
AbstractInstancePoolq有个freeҎQ?
public void free(EnterpriseContext ctx) {
ctx.clear();//记得ctx只是清掉id,transaction{,q回pool,准备复用么?
//discard是在发生错误的时候,不希望扩大媄响,于是discard掉,
//而对应get()的freeҎ只是把EnterpriseContextq还lpool.
}
----------------------------------------------------------------------------------

专门对于Stateful....Context有设|EJB instance的函?
/**
* During activation of stateful session beans we replace the instance
* by the one read from the file.
*/
public void setInstance(Object instance)
{
this.instance = instance;
((SessionBean)instance).setSessionContext(ctx);
}
注意?U?..Context中,只有Stateful...Context{֐
public class StatefulSessionEnterpriseContext
extends EnterpriseContext
implements Serializable
多了个implements Serializable,(其他都没?,
q是Z支持Activation/Passviation,Passviation的时?
把EJB Instance写到文g中?
在StatefulSessionEnterpriseContext中有q样两个Ҏ
private void writeObject(ObjectOutputStream out)
throws IOException, ClassNotFoundException
{
// do nothing
}

private void readObject(ObjectInputStream in)
throws IOException, ClassNotFoundException
{
// do nothing
}
//说明序列化的时候StatefulSessionEnterpriseContext本n不需?
写出什么状态,只有对应的EJB instance才需要写出状态?BR>
现在来看AbstractInstancePool的源码,׃内容太多
׃详细解释了?

先看Abstract...Pool的create(Object instance)函数热热w~
Abstract...Pool
// Protected -----------------------------------------------------
protected abstract EnterpriseContext create(Object instance)
throws Exception;
对Entity...Pool
protected EnterpriseContext create(Object instance)
throws Exception
{
return new EntityEnterpriseContext(instance, getContainer());
}
其他3UPoolcM?
再回头看Abstract..Pool
/** The pool data structure */
protected EnterpriseContext[] pool;
protected int currentIndex = -1;
/** The maximum number of instances allowed in the pool */
protected int maxSize = 30;
/** The minimum size of the pool */
protected int minSize = 0;
/** determine if we reuse EnterpriseContext objects i.e. if we actually do pooling */
protected boolean reclaim = false;//对于MDB和StatelessSessionBean,q个变量被设为true,// for MDB, we *do* pool // for SLSB, we *do* pool

ok,现在来看pool的重头戏Qget()/free(EnterpriseContext ctx)函数
Qdiscard(EnterpriseContext ctx)前面讲过Q不再重?
q几个函C是Interface InstancePool里头要实现的接口Q)
闲话说Q来看代码~~
protected boolean minSizeInitialized = false;


/**
* Get an instance without identity.
* Can be used by finders,create-methods, and activation
*
* @return Context /w instance
* @exception RemoteException
*/

public EnterpriseContext get() {
//pool里头有东东就拿出?
synchronized (pool)
{
if (currentIndex > -1)
{
EnterpriseContext ctx = pool[currentIndex];
pool[currentIndex--] = null;
return ctx;
}
}

//initialize a small fixed size of instance at startup.
if (!minSizeInitialized)
{
minSizeInitialized = true;
synchronized (pool)
{
for (int i = 0; i < minSize; i++)
{
pool[++currentIndex] = create(container.createBeanClassInstance());
}
}
}

// Pool is empty, create an instance
return create(container.createBeanClassInstance());
}

/**
* Return an instance after invocation.
*
* Called in 2 cases:
* a) Done with finder method
* b) Just removed
*
* @param ctx
*/
public void free(EnterpriseContext ctx) {
ctx.clear();
synchronized (pool)
{
if (currentIndex + 1 < maxSize)
{
pool[++currentIndex] = ctx;
}
}
}
对于Entity...Pool,他overwrite了free
/**
* Return an instance to the free pool. Reset state
*
*

Called in 3 cases:
*


    *
  • Done with finder method
    *
  • Removed
    *
  • Passivated
    *

*
* @param ctx
*/
public void free(EnterpriseContext ctx)
{
// If transaction still present don\\\\\\\\\\\\\\\'t do anything (let the instance be GC)
if (ctx.getTransaction() != null)
{
return ;
}
super.free(ctx);
}

-----------------------------------------------------
而Stateful....Pool的freeҎoverwrite了Abstract...Pool的,
public synchronized void free(EnterpriseContext ctx)
{
discard(ctx);//q脆discard掉不用了~
}

剩下的下回再Ԍ先预?个类体系Q?
1.AbstractInstanceCache ,有EntityInstanceCache和StatefulSessionInstanceCache 子类。对于Entity,用它?
PrimaryKey作Cache的Key,对于Stateful,Jboss也会付给
每个instance一个唯一标定的值用来做CacheKey.
Abstract...Cache与Abstract...Pooll合使用Q得到好的Performance?
2.public abstract class Container,
有EntityContainer,MessageDrivenContainer,Stateful/StatelessSessionContainer
4个子c,用来提供对EJB instance的transaction/security/pool{服务?
//看看它的成员变量Q就能猜个大?
/** This is the TransactionManager */
protected TransactionManager tm;

/** This is the SecurityManager */
protected AuthenticationManager sm;

/** This is the instancepool that is to be used */
protected InstancePool instancePool;
 
开始讲Container,以前说过Container?U子c,分别对应4U类型的EJB.
一个Container是所有Container plugins(?)和metadata(?)的集散地Qthe container plugins可以从container拿到metadata和其他container plugins.EJB部v的时候会创徏相应的Container.Container基本不做太多事,主要delegatelplugins作事情?
ok,让我们来看看Container的成员变量:
/**
* This is the new metadata. it includes information from both ejb-jar and
* jboss.xml the metadata for the application can be accessed trough
* metaData.getApplicationMetaData()
*/
protected BeanMetaData metaData;

/** This is the EnterpriseBean class */
protected Class beanClass;

/** This is the Home interface class */
protected Class homeInterface;

/** This is the Remote interface class */
protected Class remoteInterface;

/** The local home interface class */
protected Class localHomeInterface;

/** The local inteface class */
protected Class localInterface;

/** This is the TransactionManager */
protected TransactionManager tm;

/** This is the SecurityManager */
protected AuthenticationManager sm;

/** This is the realm mapping */
protected RealmMapping rm;

/** This is the bean lock manager that is to be used */
protected BeanLockManager lockManager;

/** This is the application that this container is a part of */
protected EjbModule ejbModule;
//ejbModule作ؓ一个单元部|的Module,比如一个ejb-jar是一个Module,
/*q个 ejb-jar里头可能有多个entitybean,sessionbean,那么对于 每个entitybean,sessionbean
都会有一个对应的container,而这些东东共享一个ejbModule.*/
/**
* Returns a new instance of the bean class or a subclass of the bean class.
* This factory style method is speciffically used by a container to supply
* an implementation of the abstract accessors in EJB2.0, but could be
* usefull in other situations. This method should ALWAYS be used instead
* of getBeanClass().newInstance();
*
* @return the new instance
*
* @see java.lang.Class#newInstance
*/
public Object createBeanClassInstance() throws Exception {
return getBeanClass().newInstance();
}
public Class getBeanClass()
{
return beanClass;
}

注意EntityContainer overwrite了这个方法:
/**
* Returns a new instance of the bean class or a subclass of the bean class.
* If this is 1.x cmp, simply return a new instance of the bean class.
* If this is 2.x cmp, return a subclass that provides an implementation
* of the abstract accessors.
*
* @see java.lang.Class#newInstance
*
* @return The new instance.
*/
public Object createBeanClassInstance() throws Exception {
return persistenceManager.createBeanClassInstance();
}
其中 persistenceManager声明为:
/** This is the persistence manager for this container */
protected EntityPersistenceManager persistenceManager;
//persitenceManager和PersistenceStore我们在W?部分讲解?
现在先给个大略印象:
BMPPersistenceManager实现
public Object createBeanClassInstance() throws Exception {
return con.getBeanClass().newInstance();
}

CMPPersistenceManager实现
EntityPersistenceStore store;
public Object createBeanClassInstance() throws Exception
{
return store.createBeanClassInstance();
}
-------------------------------------------------------------------
ok,接下来看看Container如何处理Clientq来的Invocation?
一切精彩尽在下面这个函?
public Object invoke(Invocation mi)Q?
//Invocation代表了Client端过来的调用
//Invocation里头有些成员变量Q指明了要调用的Method,
//args,Transaction信息Qprinciple/credential{信息?

/** Maps for MarshalledInvocation mapping */
protected Map marshalledInvocationMapping = new HashMap();

public Object invoke(Invocation mi)
throws Exception
{
Thread currentThread = Thread.currentThread();
ClassLoader callerClassLoader = currentThread.getContextClassLoader();
//保存原来的classloader,在finally里恢?

Method m = null;
Object type = null;

try
{
currentThread.setContextClassLoader(this.classLoader);(?Q?
// Check against home, remote, localHome, local, getHome,
// getRemote, getLocalHome, getLocal
type = mi.getType();

if(type == InvocationType.REMOTE ||
type == InvocationType.LOCAL)
{
if (mi instanceof MarshalledInvocation)
{
((MarshalledInvocation) mi).setMethodMap(
marshalledInvocationMapping);
}
return internalInvoke(mi);
}
else if(type == InvocationType.HOME ||
type == InvocationType.LOCALHOME)
{
if (mi instanceof MarshalledInvocation)
{
((MarshalledInvocation) mi).setMethodMap(
marshalledInvocationMapping);
return internalInvokeHome(mi);
}
else
{
throw new MBeanException(new IllegalArgumentException(
\\\\\\\"Unknown invocation type: \\\\\\\" + type));
}
}
finally
{
currentThread.setContextClassLoader(callerClassLoader);
}
}

----------------------------------------------------------------
MarshalledInvocation是Invocation的字c,代表可以?
Client传到Server的Invocation
public class Invocation...

public class MarshalledInvocation
extends Invocation
implements java.io.Externalizable
而Invocation是在server端的调用?Interceptor链,?Q?
间传?
-------------------------------------------------------
ok,E喘口气Q接下来看看两个Internal的invoke,
都是abstract,在字cd?
public abstract Object internalInvokeHome(Invocation mi)
throws Exception;
public abstract Object internalInvoke(Invocation mi)
throws Exception;
至于具体实现么,TO BE CONITUE?)
----------------------------------------------------
?QContainerPlugin可以攑֜容器里头的东东?
接口为interface ContainerPlugin Q?
void setContainer(Container con);
有InstancePool,InstanceCache,EJBProxyFactory/LocalProxyFactory,
EntityPersistenceManager/EntityPersistenceStore{Plugin
?Qmetadata描述部v的信息,比如ejb-jar.xmlQ描qC么东东是
entitybean,什么东东是sessionbean,session的是BMP/CMP{等?
?Q?Container的成员变量protected ClassLoader classLoader;
用来load q个Container里头的类和资源,之所以要专门设一个Container
的classLoader是因使EJB re-deployable.(JBoss定期扫描deploy目录Q?
如果ejb更改p行redeploy,如果ejb删除undeploy)
?Q?Jboss会徏立一个Interceptor 链,Invocationl过链传递?
比如有EntityInterceptorQSecurityInterceptorQTransactionInterceptorQ?
InvokerInterceptorQ一个套一个,每个Interceptor对当前Invocationq行一些处?
Q比如检查权限,事物{等Q然后传l下一个Interceptor处理(q是Filter and Pipe模式了,也算是AOP拉~Q别
JBoss q个Interceptor实现属于AOP方言特别重:Q?
所有的Interceptor都是?
Object invokeHome(Invocation mi) throws Exception;
和Object invoke(Invocation mi) throws Exception;
在自己invoke的最后,
l过所有的Interceptor之后Q调用下一个?
看看AbstractInterceptor的缺省实玎ͼ
public abstract class AbstractInterceptor
implements Interceptor

public Object invokeHome(final Invocation mi) throws Exception {
//do sth.
return getNext().invokeHome(mi);
}
public Object invoke(final Invocation mi) throws Exception {
//do sth.
return getNext().invoke(mi);
}
在经q重重Interceptor之后
最后到达EJB Instance 调用你要的那个方法?BR>
其实实现很简单:
public Object internalInvokeHome(Invocation mi) throws Exception
{
return getInterceptor().invokeHome(mi);
}

public Object internalInvoke(Invocation mi) throws Exception
{
// Invoke through interceptors
return getInterceptor().invoke(mi);
}

public Interceptor getInterceptor()
{
return interceptor;
}
protected Interceptor interceptor;
//q是Container建立的Interceptor铄头一个,从这里调起~
再来看看 void addInterceptor(Interceptor in);q个函数
在Interceptor链最后再挂一个Interceptor
public void addInterceptor(Interceptor in)
{
if (interceptor == null)
{
interceptor = in;
}
else
{
Interceptor current = interceptor;
while (current.getNext() != null)
{
current = current.getNext();
}

current.setNext(in);
}
}
------------------------------------------------------------------------
附带再提一下pool和cache
/** This is the instance cache for this container */
protected InstanceCache instanceCache;

/** This is the instancepool that is to be used */
protected InstancePool instancePool;
/** This is the instancepool that is to be used */
protected InstancePool instancePool;
-------------------------------------------------------------
public void setInstanceCache(InstanceCache ic)
{
if (ic == null)
throw new IllegalArgumentException(\\\"Null cache\\\");

this.instanceCache = ic;
ic.setContainer(this);
}

public InstanceCache getInstanceCache()
{
return instanceCache;
}
public void setInstancePool(InstancePool ip)
{
if (ip == null)
throw new IllegalArgumentException(\\\"Null pool\\\");

this.instancePool = ip;
ip.setContainer(this);
}
-----------------------------------------------------------------------
ok,现在让我们来看看Container都对EJB Instance暴露出来?
Ҏ都作了些什么,q有如何调用EJB Instance的方?
q里有重要的2个Map
/**
* These are the mappings between the home interface methods and the
* container methods.
* 所有Home Ҏ映射都存q里
*/
protected Map homeMapping = new HashMap();

/**
* These are the mappings between the remote/local interface methods and the
* bean methods.
* 所有EJBObjectҎ映射都存q里
*/
protected Map beanMapping = new HashMap();
--------------------------------------------------------------------------
class ContainerInterceptor
extends AbstractContainerInterceptor
//AbstractContainerInterceptor基本上什么都不做Q不用看
//ContainerInterceptor代表Container setup的Interceptor调用
//铄最后一个,到这里你׃看到他调用了你的EJB Instance的方?
{
public Object invokeHome(Invocation mi) throws Exception
{
// Invoke and handle exceptions
Method miMethod = mi.getMethod();
Method m = (Method) homeMapping.get(miMethod);
if (m.getDeclaringClass().equals(EntityContainer.class))
{
try
{
return m.invoke(EntityContainer.this, new Object[] { mi });
}
catch (Exception e)
{
rethrow(e);
}
}
else // Home method
{
try
{
return m.invoke(((EnterpriseContext) mi.getEnterpriseContext()).getInstance(), mi.getArguments());
}
catch (Exception e)
{
rethrow(e);
}
}

// We will never get this far, but the compiler does not know that
throw new org.jboss.util.UnreachableStatementException();
}

public Object invoke(Invocation mi) throws Exception
{
// Get method
Method miMethod = mi.getMethod();
Method m = (Method) beanMapping.get(miMethod);
if( m == null )
{
String msg = \\\"Invalid invocation, check your deployment packaging\\\"
+\\\", method=\\\"+miMethod;
throw new EJBException(msg);
}

// Select instance to invoke (container or bean)
if (m.getDeclaringClass().equals(EntityContainer.class))
{
// Invoke and handle exceptions
try
{
return m.invoke(EntityContainer.this, new Object[]{ mi });
}
catch (Exception e)
{
rethrow(e);
}
}
else
{
// Invoke and handle exceptions
try
{
return m.invoke(((EnterpriseContext) mi.getEnterpriseContext()).getInstance(), mi.getArguments());
}
catch (Exception e)
{
rethrow(e);
}
}

// We will never get this far, but the compiler does not know that
throw new org.jboss.util.UnreachableStatementException();
}
}

//可以看到Q两个Map作了个映,Map的Key?
在你惌调用的EJB instanceҎQvalue为实?
实现的方法,可能是EJB instance本n实现的方法,
或者是容器帮忙实现?比如CMP 中abstract get/setҎQ?
只能容器帮忙实现).
从这里也可以看出来,JBoss主要是保存了Ҏ映射来处?
EJBObject/EJBLocalObject 的调用请?
而其他一些J2EE AS是通过动态生成EJBObject/EJBLocalObject
和你的EJB Instance的字cL实现的(而JBossq在CMP2.0
里动态生成了一个东东,那也不是EJB Instance的子c??/DIV>
 
ok,基本弄明白了Container的原理之后,我们来看?
到底Container的一些初始化操作
Container是一Ҏ务,
JBoss在deploy/undeploy/redeploy时会调用
与Service相关的几个函敎ͼ
protected void createService() throws Exception {}
protected void startService() throws Exception {}
protected void stopService() throws Exception {}
protected void destroyService() throws Exception {}
让我们从EntityContainer看vQ?

protected void createService() throws Exception
{
// Associate thread with classloader
ClassLoader oldCl = Thread.currentThread().getContextClassLoader();
Thread.currentThread().setContextClassLoader(getClassLoader());

try
{
// Acquire classes from CL
//从metadata拿到Home/Remote的Class
if (metaData.getHome() != null)
homeInterface = classLoader.loadClass(metaData.getHome());
if (metaData.getRemote() != null)
remoteInterface = classLoader.loadClass(metaData.getRemote());

// Call default init
// 调用Container里头的CreateService,我们回头再看
super.createService();

//建立刚才所说的两个Method映射Map
setupBeanMapping();
setupHomeMapping();

// Map the interfaces to Long
setupMarshalledInvocationMapping();

// Initialize pool
instancePool.create();
// Try to register the instance pool as an MBean
try
{
ObjectName containerName = super.getJmxName();
Hashtable props = containerName.getKeyPropertyList();
props.put(\\\"plugin\\\", \\\"pool\\\");
ObjectName poolName = new ObjectName(containerName.getDomain(), props);
server.registerMBean(instancePool, poolName);
}
catch(Throwable t)
{
log.debug(\\\"Failed to register cache as mbean\\\", t);
}

// Init instance cache
instanceCache.create();
// Try to register the instance cache as an MBean
try
{
ObjectName containerName = super.getJmxName();
Hashtable props = containerName.getKeyPropertyList();
props.put(\\\"plugin\\\", \\\"cache\\\");
ObjectName cacheName = new ObjectName(containerName.getDomain(), props);
server.registerMBean(instanceCache, cacheName);
}
catch(Throwable t)
{
log.debug(\\\"Failed to register cache as mbean\\\", t);
}


for (Iterator it = proxyFactories.keySet().iterator(); it.hasNext(); )
{
String invokerBinding = (String)it.next();
EJBProxyFactory ci = (EJBProxyFactory)proxyFactories.get(invokerBinding);
ci.create();
}



// Init persistence
persistenceManager.create();

// Initialize the interceptor by calling the chain
Interceptor in = interceptor;
while (in != null)
{
in.setContainer(this);
in.create();
in = in.getNext();
}
readOnly = ((EntityMetaData)metaData).isReadOnly();
}
finally
{
// Reset classloader
Thread.currentThread().setContextClassLoader(oldCl);
}
}



protected void startService() throws Exception
{
// Associate thread with classloader
ClassLoader oldCl = Thread.currentThread().getContextClassLoader();
Thread.currentThread().setContextClassLoader(getClassLoader());

try
{
// Call default start
super.startService();

// Start container invokers
for (Iterator it = proxyFactories.keySet().iterator(); it.hasNext(); )
{
String invokerBinding = (String)it.next();
EJBProxyFactory ci = (EJBProxyFactory)proxyFactories.get(invokerBinding);
ci.start();
}

// Start instance cache
instanceCache.start();

// Start persistence
persistenceManager.start();

// Start the instance pool
instancePool.start();

// Start all interceptors in the chain
Interceptor in = interceptor;
while (in != null)
{
in.start();
in = in.getNext();
}
}
finally
{
// Reset classloader
Thread.currentThread().setContextClassLoader(oldCl);
}
}

protected void stopService() throws Exception
{
// Associate thread with classloader
ClassLoader oldCl = Thread.currentThread().getContextClassLoader();
Thread.currentThread().setContextClassLoader(getClassLoader());

try
{
//Stop items in reverse order from start
//This assures that CachedConnectionInterceptor will get removed
//from in between this and the pm before the pm is stopped.
// Stop all interceptors in the chain
Interceptor in = interceptor;
while (in != null)
{
in.stop();
in = in.getNext();
}

// Stop the instance pool
instancePool.stop();


// Stop persistence
persistenceManager.stop();

// Stop instance cache
instanceCache.stop();

// Stop container invoker
for (Iterator it = proxyFactories.keySet().iterator(); it.hasNext(); )
{
String invokerBinding = (String)it.next();
EJBProxyFactory ci = (EJBProxyFactory)proxyFactories.get(invokerBinding);
ci.stop();
}

// Call default stop
super.stopService();
}
finally
{
// Reset classloader
Thread.currentThread().setContextClassLoader(oldCl);
}
}

protected void destroyService() throws Exception
{
// Associate thread with classloader
ClassLoader oldCl = Thread.currentThread().getContextClassLoader();
Thread.currentThread().setContextClassLoader(getClassLoader());

try
{
// Destroy container invoker
for (Iterator it = proxyFactories.keySet().iterator(); it.hasNext(); )
{
String invokerBinding = (String)it.next();
EJBProxyFactory ci = (EJBProxyFactory)proxyFactories.get(invokerBinding);
ci.destroy();
}

// Destroy instance cache
instanceCache.destroy();
instanceCache.setContainer(null);
try
{
ObjectName containerName = super.getJmxName();
Hashtable props = containerName.getKeyPropertyList();
props.put(\\\"plugin\\\", \\\"cache\\\");
ObjectName cacheName = new ObjectName(containerName.getDomain(), props);
server.unregisterMBean(cacheName);
}
catch(Throwable ignore)
{
}

// Destroy persistence
persistenceManager.destroy();
persistenceManager.setContainer(null);

// Destroy the pool
instancePool.destroy();
instancePool.setContainer(null);
try
{
ObjectName containerName = super.getJmxName();
Hashtable props = containerName.getKeyPropertyList();
props.put(\\\"plugin\\\", \\\"pool\\\");
ObjectName poolName = new ObjectName(containerName.getDomain(), props);
server.unregisterMBean(poolName);
}
catch(Throwable ignore)
{
}

// Destroy all the interceptors in the chain
Interceptor in = interceptor;
while (in != null)
{
in.destroy();
in.setContainer(null);
in = in.getNext();
}

MarshalledInvocation.removeHashes(homeInterface);
MarshalledInvocation.removeHashes(remoteInterface);

// Call default destroy
super.destroyService();
}
finally
{
// Reset classloader
Thread.currentThread().setContextClassLoader(oldCl);
}
}
------------------------------------------------------------
protected void setupBeanMapping() throws Exception
{
try {
if (remoteInterface != null)
{
Method[] m = remoteInterface.getMethods();
setupBeanMappingImpl( m, \\\"javax.ejb.EJBObject\\\" );
}
if (localInterface != null)
{
Method[] m = localInterface.getMethods();
setupBeanMappingImpl( m, \\\"javax.ejb.EJBLocalObject\\\" );
}
}
catch (Exception e)
{
// ditch the half built mappings
homeMapping.clear();
beanMapping.clear();

throw e;
}
}

private void setupBeanMappingImpl( Method[] m, String intfName )
throws Exception
{
for (int i = 0; i < m.length; i++)
{
if (!m.getDeclaringClass().getName().equals(intfName))
{
// Implemented by bean
beanMapping.put(m, beanClass.getMethod(m.getName(), m.getParameterTypes()));
}
else
{
// Implemented by container
beanMapping.put(m, getClass().getMethod(m.getName(),
new Class[] { Invocation.class }));
}
}
}
private void setupHomeMappingImpl(Method[] m,
String finderName,
String append)
throws Exception
{
// Adrian Brock: This should go away when we don\\\'t support EJB1x
boolean isEJB1x = metaData.getApplicationMetaData().isEJB1x();

for (int i = 0; i < m.length; i++)
{
String methodName = m.getName();
try
{
try // Try home method
{
String ejbHomeMethodName = \\\"ejbHome\\\" + methodName.substring(0,1).toUpperCase() + methodName.substring(1);
homeMapping.put(m, beanClass.getMethod(ejbHomeMethodName, m.getParameterTypes()));

continue;
}
catch (NoSuchMethodException ignore) {} // just go on with other types of methods


// Implemented by container (in both cases)
if (methodName.startsWith(\\\"find\\\"))
{
homeMapping.put(m, this.getClass().getMethod(finderName, new Class[] { Invocation.class }));
}
else if (methodName.equals(\\\"create\\\") ||
(isEJB1x == false && methodName.startsWith(\\\"create\\\")))
{
homeMapping.put(m, this.getClass().getMethod(\\\"create\\\"+append, new Class[] { Invocation.class }));
beanMapping.put(m, this.getClass().getMethod(\\\"postCreate\\\"+append, new Class[] { Invocation.class }));
}
else
{
homeMapping.put(m, this.getClass().getMethod(methodName+append, new Class[] { Invocation.class }));
}
}
catch (NoSuchMethodException e)
{
throw new NoSuchMethodException(\\\"Could not find matching method for \\\"+m);
}
}
}

protected void setupHomeMapping() throws Exception
{
try {
if (homeInterface != null)
{
Method[] m = homeInterface.getMethods();
setupHomeMappingImpl( m, \\\"find\\\", \\\"Home\\\" );
}
if (localHomeInterface != null)
{
Method[] m = localHomeInterface.getMethods();
setupHomeMappingImpl( m, \\\"findLocal\\\", \\\"LocalHome\\\" );
}

// Special methods

// Get the One on Handle (getEJBObject), get the class
Class handleClass = Class.forName(\\\"javax.ejb.Handle\\\");

// Get the methods (there is only one)
Method[] handleMethods = handleClass.getMethods();

//Just to make sure let\\\'s iterate
for (int j=0; j {
//Get only the one called handle.getEJBObject
if (handleMethods[j].getName().equals(\\\"getEJBObject\\\"))
{
//Map it in the home stuff
homeMapping.put(handleMethods[j],
this.getClass().getMethod(\\\"getEJBObject\\\",
new Class[] {Invocation.class}));
}
}
}
catch (Exception e)
{
// ditch the half built mappings
homeMapping.clear();
beanMapping.clear();

throw e;
}
}



W笨 2005-03-29 09:46 发表评论
]]> վ֩ģ壺 | | ľ| Ƹ| ƽ| | | ͼʲ| ͨ| | | | ֵ| ɽ| | ɽ| ī| | | ɽ| ˮ| | | | Զ| | | пǰ| ɽ| | | Ϸ| | | ƽȪ| ˮ| Ҿ| ͩ®| | | |