ï»??xml version="1.0" encoding="utf-8" standalone="yes"?>日韩精品一区二区三区,国产女人aaa级久久久级,av在线播放网http://www.aygfsteel.com/SSailYang/archive/2009/04/04/263932.html阉K‡Œé˜‰K‡ŒSat, 04 Apr 2009 13:45:00 GMThttp://www.aygfsteel.com/SSailYang/archive/2009/04/04/263932.htmlhttp://www.aygfsteel.com/SSailYang/comments/263932.htmlhttp://www.aygfsteel.com/SSailYang/archive/2009/04/04/263932.html#Feedback0http://www.aygfsteel.com/SSailYang/comments/commentRss/263932.htmlhttp://www.aygfsteel.com/SSailYang/services/trackbacks/263932.html阅读全文

阉K‡Œ 2009-04-04 21:45 发表评论
]]>
Grails 1.1 ä¸?PetClinic-MVC 实例的源代码分析http://www.aygfsteel.com/SSailYang/archive/2009/03/14/259700.html阉K‡Œé˜‰K‡ŒSat, 14 Mar 2009 04:33:00 GMThttp://www.aygfsteel.com/SSailYang/archive/2009/03/14/259700.htmlhttp://www.aygfsteel.com/SSailYang/comments/259700.htmlhttp://www.aygfsteel.com/SSailYang/archive/2009/03/14/259700.html#Feedback1http://www.aygfsteel.com/SSailYang/comments/commentRss/259700.htmlhttp://www.aygfsteel.com/SSailYang/services/trackbacks/259700.html本文的主要内å®ÒŽ˜¯å¯?Grails 1.1 ä¸?PetClinic-MVC 实例的代码分析。这个实例主要验证了如何在非 Grails 的项目中使用 GORM。此外也演示äº?Spring MVC 2.5 的一些用法。本文假讑֤§å®¶å¯¹ Spring、Spring MVC、Groovy å’?Grails 有着初步的了解。OK, let's go!

Domain å±?/span>

目前 Grails 只提供了在普é€?Spring 应用中独立ä‹Éç”?GORM 的方法(现在 Groovy å’?Grails 已是 SpringSource 旗下的äñ”品了åQŒè‡ªç„¶è¦é¦–先对自家äñ”品提供支持)。不˜q‡ç›¸ä¿¡ä»¥åŽåœ¨å…¶å®ƒ Java EE 框架中也可独立ä‹Éç”?GORMã€?

åœ?Grails 以外使用 GORMåQŒåªéœ€åœ?Domain ¾cÖM¸Šä½¿ç”¨ grails.persistence.Entity 注释卛_¯ã€‚其它的ž®±åƒåœ?Grails 中的一栗÷€?/p>

在配¾|®æ–¹é¢ä¹Ÿå¾ˆç®€å•,只要使用 <gorm:sessionFactory ... /> 卛_¯ã€‚详¾l†è¯·è§?Grails çš?PetClinicåQŒè¿™é‡Œå°±ä¸æ‹—˜qîCº†ã€?/p>

Controller å±?/strong>

å?Domain å±‚ä¸€æ øP¼ŒController 层也全部使用 Groovy å®žçŽ°ã€‚ä¸»è¦æ˜¯å› äØ“ GORM 的大部分æ–ÒŽ³•都是动态的ã€?

1. ClinicController: ClinicController 实现äº?InitializingBean 接口。这个接口只有一个方æ³?afterPropertiesSet。这个方法会åœ?Bean 完成属性设¾|®ä¹‹åŽæ‰§è¡Œã€‚PetClinic 用这个方式实çŽîCº†¾cÖM¼¼ Grails ä¸?BootStrap 的部分功能。在˜q™ä¸ªæ–ÒŽ³•中我们可以看åˆ?GORM 中的 save() æ–ÒŽ³•å’? addTo* 动态方法都是可用的ã€?/p>

   1public void afterPropertiesSet() {  
   
2.     if (!Speciality.count()) {  
   
3.         def rad = new Speciality(name: "radiology").save()  
   
4  
   
5.         new Vet(firstName: "Linda", lastName: "Douglas").  
   
6.             addToSpecialities(sur).save()  
   
7  
   
8.   
   
9.         ['dog''lizard''cat''snake''bird''hamster'].each {  
  
10.             new PetType(name: it).save()  
  
11.         }  
  
12.     }  
  
13. } 


可能有äh会问åQŒafterPropertiesSet() ˜q™ä¸ªæ–ÒŽ³•的作用就是增加一些预定义的数据,ä¸ÞZ»€ä¹ˆä¸ä½¿ç”¨æž„造函数来实现。实际上åQŒåœ¨æœ¬ä¾‹ä¸­ï¼ŒafterPropertiesSet() 的作用的¼‹®å¯ä»¥ç”¨æž„造函数来实现åQˆç»˜q‡æµ‹è¯•)。至于作者是å‡ÞZºŽä»€ä¹ˆç›®çš„而选择了实çŽ?InitializingBean 接口我也说不好ã€?br />
ClinicController 的其它部分就是一些简单的不能再简单的 Http è¯äh±‚处理函数了。需要说明的一ç‚ÒŽ˜¯ @RequestMapping 中的å€ég»£è¡¨äº†è¯äh±‚çš?URLåQŒè¿™ä¸ªæ˜¯ä¸ç”¨å¸¦åŽ¾~€çš„,也就是说 ".do" 是多余的ã€?br />
2. AddPetForm:

       åœ?AddPetForm ¾cȝš„¾U§åˆ«ä¸Šæœ‰ä¸‰ä¸ªæ³¨é‡ŠåQŒåˆ†åˆ«æ˜¯ @Controller, @RequestMapping å’? @SessionAttributes。@Controller 不用多说åQŒä½œç”¨æ˜¯˜q™ä¸ª¾cÕd£°æ˜Žäؓ一ä¸?Spring ControlleråQŒåƈæ·ÕdŠ åˆ? Context 中。下面介¾lä¸€ä¸?@RequestMapping å’?@SessionAttributes 的功能:

  • @RequestMapping 可以定义处理è¯äh±‚çš„èµ\径和æ–ÒŽ³•¾cÕdž‹åQŒå³å¯æ”¾åœ¨ç±»å£°æ˜Žä¸Šï¼Œä¹Ÿå¯æ”‘Öœ¨æ–ÒŽ³•声明上。在 AddPetForm 中,¾cÕd’Œæ–ÒŽ³•上都æœ?@RequestMappingåQŒç±»ä¸Šçš„ @RequestMapping 用来定义è¯äh±‚路径。两ä¸? @RequestMapping 的方法分别负责处ç?get è¯äh±‚å’?post è¯äh±‚。但我认为更好的方式是在一ä¸?Controller ¾cÖM¸­å®šä¹‰å¤šä¸ªå¤„理è¯äh±‚的方法,ž®±åƒ Grails çš?Controller 那样。需要注意的是方法上面的 @RequestMapping ä¸Šé¢çš„å€¼åÆˆä¸ä¼šè¦†ç›–¾cÖM¸Šçš?@RequestMapping 中的倹{€?/li>
  • @SessionAttributes 中的å€ég»£è¡¨äº† org.springframework.ui.Model 中应该被讄¡½®ä¸? Session 范围的变量。在 Spring MVC 应用中,˜q™äº›å˜é‡å¾€å¾€æ˜¯è“våˆ?ActionForm(Struts) æˆ? CommandObject(Spring MVC) 的作用。之所以要ž®†è¡¨å•对象放åœ?Session ä¸­ï¼Œæ˜¯äØ“äº†ä‹É其能够在表单昄¡¤ºå’Œä¹‹åŽçš„表单提交˜q™æ ·˜q‡ç¨‹ä¸­ä¸ä¸¢å¤±ã€‚@SessionAttributes 的这¿Uç”¨æ³•是源于 Spring MVC 2.0 AbstractFormController çš?SessionForm 模式ã€?br />
    实际上,使用 @SessionAttributes 是很成问题的åQŒæœ‰æ—¶æ˜¯ä¸å¯æŽ¥å—的。考虑以下场景åQšåœ¨ PetClinic 应用中,新徏两个 OwneråQŒç„¶åŽäØ“˜q™ä¸¤ä¸?Owner 都添加新çš? Pet。注意,只要昄¡¤ºå‡ºæ¥ Add Pet 的页面即可。这æ—Óž¼Œ˜q™ä¸¤ä¸ªé¡µé¢çš„ URL 应该æ˜?addPet.do?ownerId=num1 å’? addPet.do?ownerId=num2 。这时将先打开的表å?/span> 提交 åQŒå‡è®¾æ˜¯ num1 的那个。你会发çŽîC½  实际上是ä¸?num2 Owner æ·ÕdŠ äº†ä¸€ä¸?Petã€?br />
    ˜q™ä¸ªé—®é¢˜çš„原因其实是很简单的åQŒæˆ‘ž®×ƒ¸è§£é‡Šäº†ã€‚从上面˜q™ä¸ªäº‹å®žæ¥çœ‹åQŒ@SessionAttributes 的缺点还是比较明显。是否采用这¿Uæ–¹å¼è¿˜è¦çœ‹˜q™ä¸ªé—®é¢˜å¯¹ä½ çš„应用的影响是否是致命的了。Spring MVC 有必要改˜q›ä¸€ä¸‹ï¼Œåƒ?Seam 那样可以很方便的使用 Conversation 是解决问题的一个好办法。(当然也可以ä‹Éç”?hidden 域来保存 idåQ‰ã€?br />
    Spring MVC 之所以要使用˜q™ç§æœ‰è¾ƒæ˜Žæ˜¾¾~ºé™·çš„æ–¹å¼çš„原因是要使用 Spring MVC 的表单数据绑定功能。由于目前还没有扑ֈ°æ›´å¥½çš„æ–¹å¼ï¼Œæ‰€ä»¥åªèƒ½ä‹Éç”?@SessionAttribute 了。这一块还æ˜?Spring MVC 的一个短板,需要在新版本中改进ã€?br />

除此以外åQŒAddPetForm 中还有两个特ŒDŠçš„æ–ÒŽ³•åQŒä¸€ä¸ªæ˜¯æ³¨é‡Šäº?@ModelAttribute 的方法;另一个是注释äº?@InitBinder 的方法。下面分别介¾lä¸€ä¸‹ï¼š

  • @ModelAttribute 可以用在æ–ÒŽ³•上,也可以用在åŞ参上。如果放在方法上åQŒé‚£å®ƒä¼šåœ¨è¿›å…¥è¯·æ±‚处理方法是准备一些数据,作用å’? SimpleFormController çš?referenceData() 一栗÷€‚@ModelAttribute 的这¿Uç”¨æ³•可能会让äh联想åˆ? Seam 中的 @Factory。但è¢?@ModelAttribute 注释的方法只会在同一ä¸?Controller 中被注释äº? @RequestMapping 的方法调用之前被调用åQŒè€?@Factory æ–ÒŽ³•则是全局的ã€?br />
    你可以在 setupForm æ–ÒŽ³•中向 request æˆ?session 中设¾|®ä¸€äº›éœ€è¦æ˜¾½Cºåœ¨™åµé¢ä¸Šçš„æ•°æ®åQŒä½†æ˜¯å¦‚果只攑֜¨ request 里的话,在表单验证发生时åQŒæ•°æ®ä¾¿ä¼šä¸¢å¤±ï¼›æ”‘Öœ¨ session ¾~ºç‚¹è‡ªä¸å¿…多说。在 Spring Web Flow 新加入的 flow å’?conversation ½{‰æ–°çš?scope 无法很容易地åœ?Spring MVC 中ä‹É用的情况下,使用 @ModelAttribute æ— ç–‘æ˜¯æ›´å¥½çš„é€‰æ‹©ã€‚åÆˆä¸”ä‹Éç”?@ModelAttribute 可以在多ä¸? @RequestMapping æ–ÒŽ³•之间实现代码的重用ã€?br />
  • @InitBinder 适用于注册只属于æœ?Controller 的属性编辑器。但åœ?AddPetForm 中,@InitBinder æ–ÒŽ³•只是告诉 Spring MVCåQŒèµ\径䨓åQ?lt;form: input path="id" />åQ?id çš„å€ég¸è¦ä‹É用属性编辑器。不˜q‡é¡µé¢é‡Œä¹ŸåŽ‹æ Ò޲¡æœ?路径ä¸?id 的倹{€‚所以,我觉得这个又是一个多余的代码。(我试˜q‡å°† @InitBinder æ–ÒŽ³•注释掉,对程序没有媄响)

Controller 层中两个ç‰ÒŽ®Šçš„ç±»åQšClinicBindingInitializer å’?PetTypeEditor

  • ClinicBindingInitializer 的作用是注册全句的属性编辑器
  • PetTypeEditor 是用于处ç?PetType ¾cÕdž‹æ•°æ®¾l‘定的属性编辑器ã€?strong>对于åƒ?PetType ˜q™æ ·çš„实体之间的兌™”属性,恰当åœîC‹É用属性编辑器可以½Ž€åŒ–程序的开发ã€?/span> åQˆä¸çŸ?Grails 是否实现了一个动态的属性编辑器åQŒç”¨äºŽå…³è”属性的数据¾l‘定åQ?/li>

 

配置

1. applicationContext.xml

        applicationContext 中大部分都是常见çš?Spring 配置。特ŒDŠä¸€ç‚¹çš„配置除了 <gorm:sessionFactory ... /> 以外åQŒè¿˜æœ?Hibernate StatisticsService JMX 的配¾|®ã€?/p>

2. dispatcher-servlet.xml

        Spring MVC 配置文äšgåQˆä¹Ÿæ˜¯ä¸€ä¸?Spring 的配¾|®æ–‡ä»Óž¼‰çš„默认名æ˜?dispatcher-servlet.xmlã€?/p>

        从上至下åQŒç¬¬ä¸€ä¸ªé…¾|®è¡¨æ˜Žå“ªä¸?Package 下的 Class 使用äº?Spring çš?@Controller 注释。这æ ?Spring 容器在启动的时候会自动扫描其下çš?ClassåQŒå°†åŠ æ³¨äº?@Controller 注释的类加入åˆ?Spring 的容器中ã€?

        ½W¬äºŒä¸ªé…¾|?DefaultAnnotationHandlerMapping æ˜?HandlerMapping 接口的一个最常用的实现类。用于映ž®?Handler 和请求èµ\径之间的关系。通过˜q™æ ·çš„配¾|®ï¼ŒController 中的 @RequestMapping 中的路径值就可以真正地和 Http è¯äh±‚对应èµäh¥ã€‚HandlerMapping 的另外一个常用的实现¾cÀL˜¯ ControllerClassNameHandlerMapping ã€?/p>

        ½W¬ä¸‰ä¸ªé…¾|?AnnotationMethodHandlerAdapter 的作用是使处理请求的 Handler èƒ½å¤ŸçœŸæ­£çš„å…·æœ‰å¤„ç†è¯·æ±‚çš„èƒ½åŠ›è€Œæä¾›ä¸€äº›æœåŠ¡ï¼ŒåŒ…æ‹¬ä¸ø™¯·æ±‚参数绑定应用相应的属性编辑器åQˆé€šè¿‡æ³¨å†Œ webBindingInitializer 实现åQ‰ã€?/p>

 

==============================¾l“束的分割线==============================

写到˜q™é‡ŒåQŒPetClinic-MVC 中值得分析学习的代码都提到了。PetClinic-MVC 是一个很ž®çš„应用åQŒä½†æ˜¯å…¶ä¸­æ¼”½CÞZº† GORM 在普é€?Spring 中的应用å’? Spring MVC 2.5 çš„ä‹É用。细看的话还是能学到不少东西的。我所写的只是我的理解åQŒéš¾å…ä¼šæœ‰ä¸€äº›ä¸­‘›_’Œé”™è¯¯åQŒæ¬¢˜qŽçº æ­£ã€?/span>



阉K‡Œ 2009-03-14 12:33 发表评论
]]>
Hibernate çš?getCurrentSession ½Ž€æž?/title><link>http://www.aygfsteel.com/SSailYang/archive/2008/07/16/215231.html</link><dc:creator>阉K‡Œ</dc:creator><author>阉K‡Œ</author><pubDate>Wed, 16 Jul 2008 07:48:00 GMT</pubDate><guid>http://www.aygfsteel.com/SSailYang/archive/2008/07/16/215231.html</guid><wfw:comment>http://www.aygfsteel.com/SSailYang/comments/215231.html</wfw:comment><comments>http://www.aygfsteel.com/SSailYang/archive/2008/07/16/215231.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/SSailYang/comments/commentRss/215231.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/SSailYang/services/trackbacks/215231.html</trackback:ping><description><![CDATA[<span style="font-size: 10pt;"><span style="font-family: 宋体;">SessionFactory.getCurrentSession() æ˜?Hibernate 应用获取 Session 的常用方法。在调用该方法时åQŒHibernate 会从 interface CurrentSessionContext 获取当前çš? SessionåQŒè¿™æ˜¯Hibernate 在不同组件中传é€?Session 的方法ã€?br id="rx2v" /> <br id="rx2v0" /> CurrentSessionContext 有三个实玎ͼŒåˆ†åˆ«æ˜? ThreadLocalSessionContext、JTASessionContext å’? ManagedSessionContext。ThreadLocalSessionContext ž®?Session 与当前线½E‹ç»‘定,是ä‹É用较多的一¿Uæ–¹æ¡ˆï¼›JTASessionContext ž®?Session ä¸?JTA 事务¾l‘定åQŒåœ¨ JTA 环境中ä‹É用;ManagedSessionContext 使应用可以通过 bind() å’?unbind() æ–ÒŽ³•控制 Session 的绑定,主要在有 Conversation 的应用中使用åQˆå¦‚æžœä‹Éç”? ManagedSessionContextåQŒå¼€å‘äh员要做的事情˜q˜æ˜¯å¾ˆå¤šçš„)。CurrentSessionContext 实现的选择可以通过 hibernate.current_session_context_class 来配¾|®ã€?br id="v:ca" /> <br id="v:ca0" /> 另一¿Uæ›´å¸¸è§çš„创å»?Session 的方法是 openSession()。openSession() ä¸? getCurrentSession() 有何不同和关联呢åQŸåœ¨ SessionFactory 启动的时候,Hibernate 会根据配¾|®åˆ›å»ºç›¸åº”çš„ CurrentSessionContextåQŒåœ¨ getCurrentSession() 被调用的时候,实际被执行的æ–ÒŽ³•æ˜? CurrentSessionContext.currentSession() 。在 currentSession() 执行æ—Óž¼Œå¦‚果当前 Session 为空åQŒcurrentSession 会调ç”?SessionFactory çš?openSession。所ä»? getCurrentSession() 对于 Java EE 来说是更好的获取 Session 的方法ã€?br id="gr:f" /> <br id="gr:f0" /> 再说 ManagedSessionContextåQŒå®ƒæä¾›äº†æ›´ç‰|´»çš„绑å®?Session 的方式,但是使用èµäh¥åŽÖM¸½Ž€å•。在 Hibernate çš?CaveatEmptor 实例中有关于使用 ManagedSessionContext 的例子,但更好的选择是ä‹Éç”?Seam Frameworkã€?br id="y31y" /> </span></span> <img src ="http://www.aygfsteel.com/SSailYang/aggbug/215231.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/SSailYang/" target="_blank">阉K‡Œ</a> 2008-07-16 15:48 <a href="http://www.aygfsteel.com/SSailYang/archive/2008/07/16/215231.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>EJB 3.0 ä¸?Seam-managed Persistence Contexthttp://www.aygfsteel.com/SSailYang/archive/2008/06/14/207944.html阉K‡Œé˜‰K‡ŒSat, 14 Jun 2008 13:59:00 GMThttp://www.aygfsteel.com/SSailYang/archive/2008/06/14/207944.htmlhttp://www.aygfsteel.com/SSailYang/comments/207944.htmlhttp://www.aygfsteel.com/SSailYang/archive/2008/06/14/207944.html#Feedback0http://www.aygfsteel.com/SSailYang/comments/commentRss/207944.htmlhttp://www.aygfsteel.com/SSailYang/services/trackbacks/207944.html

本文ž®†ç®€å•谈谈我å¯?EJB 3.0 的两¿U?Persistence Context å’?Seam-managed Persistence Context 的不同点的理解、所要解决的问题和我自己所疑惑的问题ã€?br />
EJB 3.0 (JPA) çš?Persistence Context

    大家在ä‹Éç”?EJB 3.0 的时候会注意åˆ?EJB 3.0 中的容器½Ž¡ç† Persistence Context 有两¿Uç±»åž‹ï¼Œä¸€¿Uæ˜¯ TransactionåQŒå¦ä¸€¿Uæ˜¯ Extended。这是一个较 Hibernate çš?Session 所没有的概念,Session 没有两种不同的类型,而且最重要的是 Session 不是容器½Ž¡ç†çš„,˜q™é‡Œçš„容器指的是 App Server 容器。这里暂时不谈论 Persistence Context ä¸?Session 之间的异同,主要谈谈两种 Persistence Context 之间的不同。学˜q?ORM 的同学都知道åQŒå½“ Persistence Context 是打开状态的时候,Model ž®±å¤„于被½Ž¡ç†çš„状态中åQ›å½“ Persistence Context 关闭之后åQŒModel ž®±å¤„于了 Detached 状态ã€?br />
    上面˜q™äº›ç‰ÒŽ€§å¯¹äº?Transaction æˆ?Extended çš?Persistence Context 都是一æ ïLš„åQŒä¸åŒçš„地方在于 Persistence Context 何时被打开关闭。由于绝大多数情况下 Persistence Context 是被容器½Ž¡ç†çš„(如果你不嫌篏也可以自己控åˆ?Persistence ContextåQ‰ï¼Œæ‰€ä»¥åœ¨ EJB 3.0 应用中看不到打开或关é—? Persistence Context 的代码(Spring + Hibernate 的应用也同样如此åQŒHibernate Session 的管理工作可以交¾l?Spring 来做åQ‰ã€?/p>


    其实åQŒTransaction å’?Extended Persistence Context 的不同之处也ž®±åœ¨äºŽå®¹å™¨ä½•时打开或关é—?Persistence Context。Transaction ¾cÕdž‹çš?Persistence Context 的打开和关闭是和事务的打开和关闭是同步的。也ž®±æ˜¯è¯´åœ¨ä¸€ä¸ªäº‹åŠ¡å¼€å§‹ä¹‹åŽï¼ŒPersistence Context 才会开始;在事务关闭的时候,相应çš?Persistence Context 也会被关闭ã€?br />

   Extended ¾cÕdž‹çš?Persistence Context 的打开和关闭是å’?Stateful Session Bean 的生命周期同步的åQŒæ˜¯è·¨è¶Šäº‹åŠ¡çš„ã€‚ä¹Ÿž®±æ˜¯è¯ß_¼Œä»?SFSB 的初始化开始,直到销毁,Persistence Context 都是存在的。你可以在事务之外执行写操作åQŒä½†æ˜¯è¿™æ˜¯åƈ不会执行真正的数据库操作åQŒå†™æ“ä½œåªæ˜¯æ”‘Ö…¥äº†é˜Ÿåˆ—,直到下一个事务,写操作才会真正地被执行。两者的 不同½Ž€å•说来就æ˜?Extended Persistence Context 存在的时间更é•ѝ€‚é‚£ä¸ÞZ»€ä¹ˆè¦æœ‰ä¸¤¿Uä¸åŒçš„ Persistence Context 呢?

    当一ä¸?Web è¯äh±‚到来æ—Óž¼ŒæœåŠ¡å™¨ä¼šæ‰“å¼€ä¸€ä¸ªçº¿½E‹ï¼Œ˜q™ä¸ª¾U¿ç¨‹å¯èƒ½ä¼šè°ƒç”¨ä¸€ä¸ªäº‹åŠ¡æ–¹æ³•ï¼Œ˜q™æ˜¯ä¸€ä¸ªäº‹åŠ¡ä¾¿å¼€å§‹äº†åQŒå½“˜q™ä¸ªè¯äh±‚¾l“束æ—Óž¼Œ¾U¿ç¨‹å…³é—­åQŒäº‹åŠ¡ä¹Ÿéšä¹‹¾l“束。由äº? Transaction ¾cÕdž‹çš?Persistence Context 的生存周期是在事务范围之内的åQŒæ‰€ä»¥ä¸€ä¸?Web è¯äh±‚的结束也意味着相应çš?Persistence Context 的关闭。由于多æ•?Web 应用在一‹Æ?Web è¯äh±‚内即可完成一个独立的操作åQŒæ‰€ä»¥å¤§éƒ¨åˆ†æƒ…况ä¸?Transaction çš?Persistence Context 是适用的。但是对于一些复杂的应用åQŒä¸€‹Æ¡æ“ä½œéœ€è¦è·¨­‘Šå¤š‹Æ¡è¯·æ±‚。这¿Uæƒ…况下åQŒå¦‚果依旧ä‹Éç”?Transcation çš?Persistence ContextåQŒç”±äºŽæ¯‹Æ¡è¯·æ±‚结束后åQŒç›¸åº”çš„ Persistence Context 都被关闭åQŒç›¸åº”çš„ Model ä¹Ÿå°±å˜äØ“ Detached 状态。如果接下来的请求仍焉™œ€è¦è¿™äº›å·²¾lå˜ä¸?Detached 状态的 Model ž®±éœ€è¦é‡æ–?loadåQŒä‹Éç”?merge() æ–ÒŽ³•来持久化。稍有不适就会äñ”ç”?LazyInitializationException å’? NonUniqueObjectException。同æ—Óž¼Œ˜q™ä¹Ÿæé«˜äº†æ“ä½œçš„复杂½E‹åº¦ã€?br />
    如果使用 Extended Persistence Context ž®Þpƒ½è§£å†³˜q™äº›é—®é¢˜ã€‚ç”±äº?Extended Persistence Context 的生命周期是ä¸?SFSB 的生命周期同步的åQŒæ‰€ä»¥åªè¦å¤š‹Æ¡è¯·æ±‚调用的都是同一ä¸?SFSB 中的æ–ÒŽ³•åQŒæœ‰å¤šå°‘‹Æ¡çš„è¯äh±‚åQŒPersistence Context æ€ÀL˜¯åŒä¸€ä¸ªï¼Œå…¶ä¸­çš?Model 也始¾lˆæ˜¯è¢«ç®¡ç†çš„。很好地解决äº? Persistence Context 在线½E‹ä¹‹é—´ä¼ é€’的问题åQŒä¹Ÿä¸ä¼šæœ?LazyInitializationException å’? NonUniqueObjectException 问题的发生ã€?br />
Seam-managed Persistence Context

    EJB 3.0 容器½Ž¡ç†ä¹‹ä¸‹çš?Persistence Context 很不错,能解军_¾ˆå¤šé—®é¢˜ï¼Œä½†æ˜¯˜q˜æ˜¯æœ‰äº›é—®é¢˜æ— æ³•解决。Seam 很强大,如果有些问题 EJB 容器解决不了了,没关¾p»ï¼ŒæŠ?Persistence Context 交由 Seam 来管理就 OK 了。那 Seam 都能解决哪些 EJB 不能解决的问题呢åQŸå…ˆè€ƒè™‘下面两个问题åQ?/p>

  1. Extended Persistence Context 虽然可以跨越多个事务åQŒä½†æ˜¯æ¯ä¸ªäº‹åŠ¡ç…§æ—§è°ƒæ•™ä¸è¯¯ï¼Œ˜q™å¯¹äºŽæƒ³åœ¨æƒ³è®©æ•´ä¸ªæ“ä½œä½œä¸ÞZ¸€‹Æ¡äº‹åŠ¡çš„è¯ï¼Œè¯¥å¦‚ä½•åŽ»å?/li>
  2. 如果一个业务的一¾l„请求只是调用同一ä¸?SFSB 的话åQŒé‚£ä¹?EJB çš?Extended Persistence Context 可以在线½E‹ä¹‹é—´ä¼ é€’,ä½?SFSB 的整个生命周期都使用同一ä¸?Persistence Context。但如果业务需要调用不同的 SFSB 的话åQŒå¦‚何在 SFSB 之间传递ã€?/li>
    对于½W¬ä¸€ä¸ªé—®é¢˜ï¼Œç”׃ºŽ Seam çš?JPA 实现提供者是 HibernateåQŒè€Œä¸” Hibernate 提供了一个扩展的 FlushModeType - "Manual"。通过使用˜q™ä¸ª FlushModeTypeåQŒæˆ‘们可以手工控制何时执è¡?flush() 操作。在 Seam 的文档中有关于这部分的介¾l?ã€?a target="_blank">Seam-managed persistence contexts and atomic conversations 》。文档中使用了一ŒD늮€å•的代码展示 Seam 如何实现所谓的 "atomic conversations"åQˆå…³äºŽä»£ç çš„内容我就不介¾läº†åQŒå¤§å®‰™€šè¿‡æˆ‘提供的链接来浏è§?Seam 的文档)。通过˜q™ç§æ–¹å¼åQŒäº‹åŠ¡è²Œä¼¼æ˜¯è·¨è¶Šäº†æ•´ä¸ªäº‹åŠ¡ï¼Œä½†æˆ‘è®¤äØ“ SFSB 中除了调ç”?flush() 的方法以外的其它æ–ÒŽ³•不是事务的。其实也没有必要åQŒå› ä¸ø™¿™äº›æ–¹æ³•åÆˆæ²¡æœ‰æ‰§è¡Œæ•°æ®åº“æ“ä½œï¼Œæ‰€ä»¥æ²¡æœ‰å¿…è¦ä‹É用事务。当ç„Óž¼Œå¦‚果是乐观事物的话,使用了对性能å½? 响也不大åQˆè¿™åªæ˜¯æˆ‘的一ç‚ÒŽµ…薄的理解åQŒæ¬¢˜qŽæŒ‡å‡ºé”™è¯¯ï¼‰ã€‚只有最后的调用äº?flush() 的方法有事务的必要ã€?br />
    ˜q™å°±å¼•发了一个ä×o我不解的问题。请先看˜q™ç¯‡æ–‡ç« ã€?a target="_blank">Extended Persistence Context in Stateful Session Beans 》。在˜q™ç¯‡æ–‡ç« ä»‹ç»äº†å¦‚何只使用 EJB 3.0 去解å†?#8220;问题1”。文中的 SFSB 的默认事务属性是 "NOT_SUPPORTED"åQŒä¹Ÿž®±æ˜¯è¯´è¿™ä¸?SFSB 中的æ–ÒŽ³•默认不是事务的。只有最后的调用 flush() 的方法ä‹É用了 "REQUIRED" 的事务属性去覆盖默认讄¡½®ã€‚也ž®±æ˜¯æœ€åŽçš„æ–ÒŽ³•是事务的åQŒå…¶å®ƒçš„不是。这å’?Seam 所做的有区别吗åQŸæ„Ÿè§‰æ²¡æœ‰åŒºåˆ«ã€‚但我认为像 Gavin King ˜q™æ ·çš„大牛绝不会做无用功的,那问题就æ˜?Seam 实现 "atomic conversations" 的内部细节到底是什么呢åQŸæ¬¢˜qŽå¤§å®¶å›ž½{”这个问题ã€?br />
    对于½W¬äºŒä¸ªé—®é¢˜ï¼Œå¯ä»¥é€šè¿‡ä½¿ç”¨ Seam-Managed Persistence Context 来解冟뀂Seam-manged Persistence Context 需要在 components.xml æ–‡äšg中进行配¾|®ï¼Œòq¶ä‹Éç”?@In 注入åˆ?Seam 的组件中。由äº?Seam 是一个比较新的框架技术,所以关äº?Seam 是如何ä‹É Persistence Context åœ¨ç»„ä»¶ä¸­ä¼ é€’åÆˆæ²¡æœ‰è¯¦ç»†çš„ä»‹¾lã€‚应该只是声明,然后透明åœîC‹É用即可。在一ä¸?jBPM ‹¹ç¨‹ä¸­è¢«ä½¿ç”¨åˆ°çš„ Seam ¾l„äšgåQŒå…¶ä¸­çš„ Persistence Context 应该是可以很å®ÒŽ˜“地被传递。(本不应该使用不确定的和模¾pŠçš„词语åQŒä½†æ— å¥ˆçŽ°åœ¨å…³äºŽ Seam 的文章资料还是有限,所以我也没有找到关äº?Persistence Context 在组件之间调用的例子åQ?br />
¾l“束语:˜q™ç¯‡æ–‡ç« è§£é‡Šçš„问题不多,不过都是我自å·Þqš„理解。可能有错误 的地方,‹Æ¢è¿Žå¤§å®¶æŒ‡å‡ºã€‚同æ—Óž¼Œåˆæœ‰ä¸€äº›æ–°é—®é¢˜äº§ç”Ÿäº†ï¼Œåº”该可以通过阅读 Seam 提供的例子和源代码得到解释。但 Seam 的例子只看过三个åQŒæ›´å¤šçš„˜q˜æ²¡æœ‰çœ‹ã€‚看˜q‡çš„ Seam 的源代码更可以忽略不计。ç‘ô¾l­åŠªåŠ›å§åQï¼

阉K‡Œ 2008-06-14 21:59 发表评论
]]>
Ö÷Õ¾Ö©Öë³ØÄ£°å£º ¹«°²ÏØ| ¹þ°ÍºÓÏØ| ͬÐÄÏØ| ÌúÁëÏØ| °°É½ÊÐ| ÔæÑôÊÐ| ÷ëÓÎÏØ| ÃöÇåÏØ| ¼ªÄ¾ÄËÏØ| ÂíÁúÏØ| °¢¿ËËÕÊÐ| ×Ó³¤ÏØ| ÒÁͨ| ÓͼâÍúÇø| ¸ßÓÊÊÐ| ÄϲýÊÐ| ÁéÉ½ÏØ| ºÍ¾²ÏØ| ¤Î÷ÏØ| °²¶àÏØ| ¹ã°²ÊÐ| ãòÎ÷ÏØ| ÄÏ´¨ÊÐ| ËçÑôÏØ| ½ºÖÝÊÐ| ´ó¶É¿ÚÇø| ºÎ÷ÊÐ| ÍòÄþÊÐ| ÃÉÒõÏØ| Óñ»·ÏØ| Âܱ±ÏØ| Ç­Î÷| ɨɽÊÐ| ¹Ì°²ÏØ| Ôý´ïÏØ| ³¤º£ÏØ| ͨº£ÏØ| ÑÉêÈ| ´Ó½­ÏØ| ¿Æ¼¼| Íú²ÔÏØ|