﻿<?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-鹰翔宇空-文章分类-Spring</title><link>http://www.blogjava.net/TrampEagle/category/9800.html</link><description>学习和生活
</description><language>zh-cn</language><lastBuildDate>Wed, 28 Feb 2007 12:30:05 GMT</lastBuildDate><pubDate>Wed, 28 Feb 2007 12:30:05 GMT</pubDate><ttl>60</ttl><item><title>为domain object注入依赖</title><link>http://www.blogjava.net/TrampEagle/articles/30263.html</link><dc:creator>TrampEagle</dc:creator><author>TrampEagle</author><pubDate>Sat, 11 Feb 2006 06:30:00 GMT</pubDate><guid>http://www.blogjava.net/TrampEagle/articles/30263.html</guid><wfw:comment>http://www.blogjava.net/TrampEagle/comments/30263.html</wfw:comment><comments>http://www.blogjava.net/TrampEagle/articles/30263.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/TrampEagle/comments/commentRss/30263.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/TrampEagle/services/trackbacks/30263.html</trackback:ping><description><![CDATA[<P>原文引自：<A href="http://www.javaeye.com/pages/viewpage.action?pageId=1141">http://www.javaeye.com/pages/viewpage.action?pageId=1141</A><BR><BR>作者: 冰云<BR>整理:robbin</P>
<DIV class=panel>
<DIV class=panelContent>
<P>原理：利用Hibernate3提供的PostLoadEventListener在loadHibernate实体类的时候触发PostLoadEvent事件，编写一个自定义的事件监听器，注入依赖的Spring Bean对象</P></DIV></DIV>
<DIV class=code>
<DIV class=codeHeader><B>SpringHibernateInjector</B></DIV>
<DIV class=codeContent><PRE class=code-java><SPAN class=code-keyword>import</SPAN> org.hibernate.event.PostLoadEvent;
<SPAN class=code-keyword>import</SPAN> org.hibernate.event.PostLoadEventListener;
<SPAN class=code-keyword>import</SPAN> org.springframework.beans.factory.BeanFactory;
<SPAN class=code-keyword>import</SPAN> org.springframework.beans.factory.BeanFactoryAware;
<SPAN class=code-keyword>import</SPAN> org.springframework.beans.factory.config.AutowireCapableBeanFactory;

<SPAN class=code-keyword>public</SPAN> class SpringHibernateInjector <SPAN class=code-keyword>implements</SPAN> PostLoadEventListener, BeanFactoryAware{

    AutowireCapableBeanFactory beanFactory;
   
    <SPAN class=code-keyword>public</SPAN> void onPostLoad(PostLoadEvent event) {
        <SPAN class=code-object>Object</SPAN> hibernateObject = event.getEntity();
        beanFactory.autowireBeanProperties(hibernateObject, AutowireCapableBeanFactory.AUTOWIRE_BY_NAME, <SPAN class=code-keyword>false</SPAN>);   
    }

    <SPAN class=code-keyword>public</SPAN> void setBeanFactory(BeanFactory factory)  {
        beanFactory = (AutowireCapableBeanFactory) factory;
    }

}</PRE></DIV></DIV>
<DIV class=code>
<DIV class=codeHeader><B>applicationContext.xml</B></DIV>
<DIV class=codeContent><PRE class=code-xml>&lt;bean id=<SPAN class=code-quote>"sessionFactory"</SPAN>
        class=<SPAN class=code-quote>"org.springframework.orm.hibernate3.LocalSessionFactoryBean"</SPAN>&gt;
        <SPAN class=code-tag>&lt;property name=<SPAN class=code-quote>"dataSource"</SPAN>&gt;</SPAN>
            <SPAN class=code-tag>&lt;ref bean=<SPAN class=code-quote>"dataSource"</SPAN> /&gt;</SPAN>
        <SPAN class=code-tag>&lt;/property&gt;</SPAN>
        <SPAN class=code-tag>&lt;property name=<SPAN class=code-quote>"mappingResources"</SPAN>&gt;</SPAN>
            <SPAN class=code-tag>&lt;list&gt;</SPAN>
                ...domains.hbm.xml here...
            <SPAN class=code-tag>&lt;/list&gt;</SPAN>
        <SPAN class=code-tag>&lt;/property&gt;</SPAN>
        <SPAN class=code-tag>&lt;property name=<SPAN class=code-quote>"hibernateProperties"</SPAN>&gt;</SPAN>
            <SPAN class=code-tag>&lt;props&gt;</SPAN>
                <SPAN class=code-tag>&lt;prop key=<SPAN class=code-quote>"hibernate.dialect"</SPAN>&gt;</SPAN>
                    org.hibernate.dialect.Oracle9Dialect
                <SPAN class=code-tag>&lt;/prop&gt;</SPAN>
                <SPAN class=code-tag>&lt;prop key=<SPAN class=code-quote>"hibernate.query.substitutions"</SPAN>&gt;</SPAN>
                    true 1, false 0
                <SPAN class=code-tag>&lt;/prop&gt;</SPAN>
                <SPAN class=code-tag>&lt;prop key=<SPAN class=code-quote>"hibernate.show_sql"</SPAN>&gt;</SPAN>false<SPAN class=code-tag>&lt;/prop&gt;</SPAN>
            <SPAN class=code-tag>&lt;/props&gt;</SPAN>
        <SPAN class=code-tag>&lt;/property&gt;</SPAN>
       <SPAN class=code-tag>&lt;property name=<SPAN class=code-quote>"eventListeners"</SPAN>&gt;</SPAN>
          <SPAN class=code-tag>&lt;map&gt;</SPAN>
            <SPAN class=code-tag>&lt;entry key=<SPAN class=code-quote>"post-load"</SPAN>&gt;</SPAN>
              &lt;!-- This hibernate interceptor allows us to use Spring to inject services
 into Hibernate managed domain objects --&gt;   
              <SPAN class=code-tag>&lt;bean class=<SPAN class=code-quote>"yourpackage.SpringHibernateInjector"</SPAN>/&gt;</SPAN>
            <SPAN class=code-tag>&lt;/entry&gt;</SPAN>        
           <SPAN class=code-tag>&lt;/map&gt;</SPAN>
    <SPAN class=code-tag>&lt;/property&gt;</SPAN>
    <SPAN class=code-tag>&lt;/bean&gt;</SPAN></PRE></DIV></DIV>
<P>注：此方法来自于<SPAN class=nobr><A title="Visit page outside Confluence" href="http://www.thoughtworks.com/" rel=nofollow>ThoughtWorks<SUP><IMG class=rendericon height=7 alt="" src="http://www.javaeye.com/images/icons/linkext7.gif" width=7 align=absMiddle border=0></SUP></A></SPAN>的 <SPAN class=nobr><A title="Visit page outside Confluence" href="http://www.jroller.com/page/perryn" rel=nofollow>PerrynFowler<SUP><IMG class=rendericon height=7 alt="" src="http://www.javaeye.com/images/icons/linkext7.gif" width=7 align=absMiddle border=0></SUP></A></SPAN>，俺只是摘抄一下</P><!--
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
         xmlns:dc="http://purl.org/dc/elements/1.1/"
         xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
<rdf:Description
    rdf:about="http://www.javaeye.com/pages/viewpage.action?pageId=1141"
    dc:identifier="http://www.javaeye.com/pages/viewpage.action?pageId=1141"
    dc:title="为domain object注入依赖"
    trackback:ping="http://www.javaeye.com/rpc/trackback/1141"/>
</rdf:RDF>
--><!--
    Root decorator: all decisions about how a page is to be decorated via the
                    inline decoration begins here.
--><!--
    Switch based upon the context. However, for now, just delegate to a decorator
    identified directly by the context.
--><img src ="http://www.blogjava.net/TrampEagle/aggbug/30263.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/TrampEagle/" target="_blank">TrampEagle</a> 2006-02-11 14:30 <a href="http://www.blogjava.net/TrampEagle/articles/30263.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title> OpenSessionInView会不会影响性能？</title><link>http://www.blogjava.net/TrampEagle/articles/30094.html</link><dc:creator>TrampEagle</dc:creator><author>TrampEagle</author><pubDate>Fri, 10 Feb 2006 01:52:00 GMT</pubDate><guid>http://www.blogjava.net/TrampEagle/articles/30094.html</guid><wfw:comment>http://www.blogjava.net/TrampEagle/comments/30094.html</wfw:comment><comments>http://www.blogjava.net/TrampEagle/articles/30094.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/TrampEagle/comments/commentRss/30094.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/TrampEagle/services/trackbacks/30094.html</trackback:ping><description><![CDATA[原文摘自：<A href="http://forum.javaeye.com/viewtopic.php?t=17501&amp;postdays=0&amp;postorder=asc&amp;start=0">http://forum.javaeye.com/viewtopic.php?t=17501&amp;postdays=0&amp;postorder=asc&amp;start=0</A><BR><BR>
<TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR>
<TD width="100%"><A href="http://forum.javaeye.com/viewtopic.php?p=105066#105066"><IMG title=文章 height=9 alt=文章 src="http://forum.javaeye.com/templates/subSilver/images/icon_minipost.gif" width=12 border=0></A><SPAN class=postdetails>时间: 2005-12-11 12:15:26<SPAN class=gen>&nbsp;</SPAN>&nbsp; &nbsp;标题: </SPAN></TD>
<TD vAlign=top noWrap><A href="http://forum.javaeye.com/posting.php?mode=quote&amp;p=105066"><IMG title=引用回复 alt=引用回复 src="http://forum.javaeye.com/templates/subSilver/images/lang_chinese_simplified/icon_quote.gif" border=0></A> <A href="http://forum.javaeye.com/addblog.php?type=javaeye&amp;title=OpenSessionInView会不会影响性能？&amp;t=17501&amp;postdays=0&amp;postorder=asc&amp;start=0&amp;p=105066"><IMG title=将这个帖子加入我的Blog alt=将这个帖子加入我的Blog src="http://forum.javaeye.com/templates/subSilver/images/icon_blog.gif" border=0></A></TD></TR>
<TR>
<TD colSpan=2>
<HR>
</TD></TR>
<TR>
<TD colSpan=2><SPAN class=postbody></SPAN>
<TABLE cellSpacing=1 cellPadding=3 width="90%" align=center border=0>
<TBODY>
<TR>
<TD><SPAN class=genmed><B>hongliang 写道:</B></SPAN></TD></TR>
<TR>
<TD class=quote>那这么说来，假设Hibernate在第一秒拿到叻数据库连接，这个连接不还是持续15秒么？</TD></TR></TBODY></TABLE><SPAN class=postbody><BR><BR>如果是网络传输速度导致load页面需要15秒，那么时间消耗在网络传输上，本身页面执行时间很短。 <BR><BR>如果不是网络传输速度导致load页面需要15秒，那说明什么？说明这个页面的程序执行了15秒！为什么一个页面程序需要执行这么久呢？说明这个页面的数据库查询非常耗时！(纯内存操作都是ms级别的，如果都10多秒了，瓶颈只可能是数据库操作) 如果数据库查询需要15秒，请问你就算不用OpenSessionInView，你不是一样需要打开数据库连接长达15秒吗？</SPAN><SPAN class=postbody></SPAN><SPAN class=gensmall></SPAN></TD></TR></TBODY></TABLE>
<TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR>
<TD width="100%"><A href="http://forum.javaeye.com/viewtopic.php?p=105070#105070"><IMG title=文章 height=9 alt=文章 src="http://forum.javaeye.com/templates/subSilver/images/icon_minipost.gif" width=12 border=0></A><SPAN class=postdetails>时间: 2005-12-11 12:32:42<SPAN class=gen>&nbsp;</SPAN>&nbsp; &nbsp;标题: </SPAN></TD>
<TD vAlign=top noWrap><A href="http://forum.javaeye.com/posting.php?mode=quote&amp;p=105070"><IMG title=引用回复 alt=引用回复 src="http://forum.javaeye.com/templates/subSilver/images/lang_chinese_simplified/icon_quote.gif" border=0></A> <A href="http://forum.javaeye.com/addblog.php?type=javaeye&amp;title=OpenSessionInView会不会影响性能？&amp;t=17501&amp;postdays=0&amp;postorder=asc&amp;start=0&amp;p=105070"><IMG title=将这个帖子加入我的Blog alt=将这个帖子加入我的Blog src="http://forum.javaeye.com/templates/subSilver/images/icon_blog.gif" border=0></A></TD></TR>
<TR>
<TD colSpan=2>
<HR>
</TD></TR>
<TR>
<TD colSpan=2><SPAN class=postbody>我明白robbin你的意思，我说的情况就是网络传输导致的15秒。本身页面执行的时间，比如freemarker渲染一下模板，这个速度是非常快的，没问题，可是我的疑问就在于如果网络传输狠慢，会不会影响到数据库连接。 <BR><BR>假设WebWork+Hibernate+FreeMarker架构模型是这样的 <BR><BR>Request <BR>| <BR>|---other filters... <BR>| <BR>|---OpenSessionInView Filter <BR>| <BR>|-----WebWork Controller <BR>| <BR>|---Action <BR>| <BR>|---FreeMarker Result(对response.getWriter()做process()操作) <BR>| <BR>| <BR>|---OpenSessionInView Filter <BR>| <BR>|---other filters... <BR>| <BR>Request <BR><BR><BR>这里有两种情况。 <BR><BR>一是页面缓冲区足够大，足够一次性容纳所有的页面，这样渲染页面就会一次性进入缓冲区，然后返回到OpenSessionInView Filter，关闭Session，数据库连接返回池中，一切OK。 <BR><BR>第二种情况我是重点想讨论的，也是我的疑虑所在。那就是假如这个页面比较大，超出叻页面缓冲区的大小，那么渲染页面时，就拿FreeMarker/Velocity这样的模板语言来说，它执行process/merge方法，往servlet的response writer/outputStream里面写东西，写着写着，发现写不动叻，是缓冲区满叻，而这个writer/outputStream，正是服务器同用户之间建立的socket请求，于是底层代码开始先向用户传输一部分页面，传好后，又有叻新的缓冲区，FreeMarker/Velocity的方法又能向缓冲区里写东西叻。而传输页面这个过程，又耗费叻几秒钟的时间，就导致叻数据库连接被占用叻狠长的时间。 <BR><BR>可能我描述的是错误的，希望robbin指正！：）</SPAN></TD></TR></TBODY></TABLE>
<TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR>
<TD width="100%"><A href="http://forum.javaeye.com/viewtopic.php?p=105072#105072"><IMG title=文章 height=9 alt=文章 src="http://forum.javaeye.com/templates/subSilver/images/icon_minipost.gif" width=12 border=0></A><SPAN class=postdetails>时间: 2005-12-11 13:07:27<SPAN class=gen>&nbsp;</SPAN>&nbsp; &nbsp;标题: </SPAN></TD>
<TD vAlign=top noWrap><A href="http://forum.javaeye.com/posting.php?mode=quote&amp;p=105072"><IMG title=引用回复 alt=引用回复 src="http://forum.javaeye.com/templates/subSilver/images/lang_chinese_simplified/icon_quote.gif" border=0></A> <A href="http://forum.javaeye.com/addblog.php?type=javaeye&amp;title=OpenSessionInView会不会影响性能？&amp;t=17501&amp;postdays=0&amp;postorder=asc&amp;start=0&amp;p=105072"><IMG title=将这个帖子加入我的Blog alt=将这个帖子加入我的Blog src="http://forum.javaeye.com/templates/subSilver/images/icon_blog.gif" border=0></A></TD></TR>
<TR>
<TD colSpan=2>
<HR>
</TD></TR>
<TR>
<TD colSpan=2><SPAN class=postbody>我觉得这个问题归根结底就是AppServer究竟会如何实现页面输出。那么必然和具体的应用服务器实现有关系。那么至于每个AppServer究竟会怎样去实现，我就不得而知了。起码大家可以研究一下Tomcat源代码看看tomcat是如何实现的。 <BR><BR>confluence采用的就是Hibernate/Spring/Webwork架构，OpenSessionInView，以confluence这么广的使用，好像也没有听过这方面的问题投诉。</SPAN><SPAN class=postbody></SPAN><SPAN class=gensmall></SPAN></TD></TR></TBODY></TABLE>
<TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR>
<TD width="100%"><A href="http://forum.javaeye.com/viewtopic.php?p=105098#105098"><IMG title=文章 height=9 alt=文章 src="http://forum.javaeye.com/templates/subSilver/images/icon_minipost.gif" width=12 border=0></A><SPAN class=postdetails>时间: 2005-12-11 18:26:22<SPAN class=gen>&nbsp;</SPAN>&nbsp; &nbsp;标题: </SPAN></TD>
<TD vAlign=top noWrap><A href="http://forum.javaeye.com/posting.php?mode=quote&amp;p=105098"><IMG title=引用回复 alt=引用回复 src="http://forum.javaeye.com/templates/subSilver/images/lang_chinese_simplified/icon_quote.gif" border=0></A> <A href="http://forum.javaeye.com/addblog.php?type=javaeye&amp;title=OpenSessionInView会不会影响性能？&amp;t=17501&amp;postdays=0&amp;postorder=asc&amp;start=0&amp;p=105098"><IMG title=将这个帖子加入我的Blog alt=将这个帖子加入我的Blog src="http://forum.javaeye.com/templates/subSilver/images/icon_blog.gif" border=0></A></TD></TR>
<TR>
<TD colSpan=2>
<HR>
</TD></TR>
<TR>
<TD colSpan=2><SPAN class=postbody>我写了一个简单的webapp在Tomcat5.5.12上面做了一个小测试。在JSP页面里面循环1万次输出字符串，程序在远程服务器上面运行，网络是ADSL宽带，filter确实被阻塞了20秒左右。然后我另外开了一个flashget去下载服务器上的大文件，模拟网络速度比较慢的环境，filter被阻塞了50秒左右。分别做了三次测试。另外当页面下载过程中直接点击浏览器stop按钮，则JSP执行被打断，filter立刻解除阻塞，被执行完毕。 <BR><BR>结论证明，使用OpenSessionInView的时候，如果render的页面数据量非常大，并且客户端网络速度很慢的情况下，由于页面的输出时间过程很长，确实会造成filter被长时间阻塞。对于OpenSessionInViewFilter来说，就会造成数据库连接被保持很长的时间，才能被关闭。 <BR><BR>不过，对于Spring的OpenSessionInViewFilter来说，虽然数据库连接被保持了过长的时间，但是并没有锁定数据库资源，特别是事务资源。因为Spring的事务是通过TransactionInterceptor来实现的，在MVC结构中，当最后一个业务bean被调用结束以后，Transaction就已经被提交了。此后，虽然数据库连接还保持中，但是数据库资源没有锁定问题。 <BR><BR>完整的调用示意图： <BR><BR>request -&gt; (OpenSessionInViewFilter打开Session) -&gt; ServletDispatcher -&gt; Action -&gt; (打开Connection，启动事务) -&gt; spring bean -&gt; another spring bean -&gt; (提交事务) -&gt; bean执行完毕，返回Action -&gt; render view(JSP/Template) -&gt; (OpenSessionInViewFilter关闭Session和Connection)</SPAN></TD></TR></TBODY></TABLE>
<TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR>
<TD width="100%"><A href="http://forum.javaeye.com/viewtopic.php?p=105128#105128"><IMG title=文章 height=9 alt=文章 src="http://forum.javaeye.com/templates/subSilver/images/icon_minipost.gif" width=12 border=0></A><SPAN class=postdetails>时间: 2005-12-11 22:44:45<SPAN class=gen>&nbsp;</SPAN>&nbsp; &nbsp;标题: </SPAN></TD>
<TD vAlign=top noWrap><A href="http://forum.javaeye.com/posting.php?mode=quote&amp;p=105128"><IMG title=引用回复 alt=引用回复 src="http://forum.javaeye.com/templates/subSilver/images/lang_chinese_simplified/icon_quote.gif" border=0></A> <A href="http://forum.javaeye.com/addblog.php?type=javaeye&amp;title=OpenSessionInView会不会影响性能？&amp;t=17501&amp;postdays=0&amp;postorder=asc&amp;start=0&amp;p=105128"><IMG title=将这个帖子加入我的Blog alt=将这个帖子加入我的Blog src="http://forum.javaeye.com/templates/subSilver/images/icon_blog.gif" border=0></A></TD></TR>
<TR>
<TD colSpan=2>
<HR>
</TD></TR>
<TR>
<TD colSpan=2><SPAN class=postbody>robbin的分析很透彻，对于最后一点，我稍有疑问。 <BR><BR></SPAN>
<TABLE cellSpacing=1 cellPadding=3 width="90%" align=center border=0>
<TBODY>
<TR>
<TD><SPAN class=genmed><B>引用:</B></SPAN></TD></TR>
<TR>
<TD class=quote><BR>对于Spring的OpenSessionInViewFilter来说，虽然数据库连接被保持了过长的时间，但是并没有锁定数据库资源，特别是事务资源。 <BR></TD></TR></TBODY></TABLE><SPAN class=postbody><BR><BR>其实我认为数据库连接被保持过长时间有时候会有很大的问题。尤其是对于采用数据连接池的情况，如果你的数据库连接一直被保持，那么这个资源就未被释放。假设说这个数据连接池的最大连接数为15，我感觉很容易造成数据库的连接不够用。 <BR><BR>不清楚底层的实现是如何做的，或许我的疑问有些多虑。</SPAN></TD></TR></TBODY></TABLE>
<TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR>
<TD width="100%"><A href="http://forum.javaeye.com/viewtopic.php?p=105129#105129"><IMG title=文章 height=9 alt=文章 src="http://forum.javaeye.com/templates/subSilver/images/icon_minipost.gif" width=12 border=0></A><SPAN class=postdetails>时间: 2005-12-11 22:51:56<SPAN class=gen>&nbsp;</SPAN>&nbsp; &nbsp;标题: </SPAN></TD>
<TD vAlign=top noWrap><A href="http://forum.javaeye.com/posting.php?mode=quote&amp;p=105129"><IMG title=引用回复 alt=引用回复 src="http://forum.javaeye.com/templates/subSilver/images/lang_chinese_simplified/icon_quote.gif" border=0></A> <A href="http://forum.javaeye.com/addblog.php?type=javaeye&amp;title=OpenSessionInView会不会影响性能？&amp;t=17501&amp;postdays=0&amp;postorder=asc&amp;start=0&amp;p=105129"><IMG title=将这个帖子加入我的Blog alt=将这个帖子加入我的Blog src="http://forum.javaeye.com/templates/subSilver/images/icon_blog.gif" border=0></A></TD></TR>
<TR>
<TD colSpan=2>
<HR>
</TD></TR>
<TR>
<TD colSpan=2><SPAN class=postbody></SPAN>
<TABLE cellSpacing=1 cellPadding=3 width="90%" align=center border=0>
<TBODY>
<TR>
<TD><SPAN class=genmed><B>downpour 写道:</B></SPAN></TD></TR>
<TR>
<TD class=quote>robbin的分析很透彻，对于最后一点，我稍有疑问。 <BR><BR></SPAN>
<TABLE cellSpacing=1 cellPadding=3 width="90%" align=center border=0>
<TBODY>
<TR>
<TD><SPAN class=genmed><B>引用:</B></SPAN></TD></TR>
<TR>
<TD class=quote><BR>对于Spring的OpenSessionInViewFilter来说，虽然数据库连接被保持了过长的时间，但是并没有锁定数据库资源，特别是事务资源。 <BR></TD></TR></TBODY></TABLE><SPAN class=postbody><BR><BR>其实我认为数据库连接被保持过长时间有时候会有很大的问题。尤其是对于采用数据连接池的情况，如果你的数据库连接一直被保持，那么这个资源就未被释放。假设说这个数据连接池的最大连接数为15，我感觉很容易造成数据库的连接不够用。 <BR><BR>不清楚底层的实现是如何做的，或许我的疑问有些多虑。</SPAN></TD></TR></TBODY></TABLE><SPAN class=postbody><BR><BR>按道理来说，数据库连接应该尽早被释放，以缓解数据库资源的压力，延迟很久才释放，确实会导致需要更多的数据库连接。这个就只能扩大连接池数量，增加数据库最大允许连接数来解决了。 <BR><BR>此外，Session被延迟很久释放，那么Session占用的一级缓存也会占用比较长时间，这意味着会无谓消耗更多的JVM内存。 <BR><BR>因此，OpenSessionInView虽然确实方便，但是大家还是慎用吧。对于那些页面渲染速度很慢，拨号连接用户数量过多的网站就最好不要使用。</SPAN></TD></TR></TBODY></TABLE>
<TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR>
<TD width="100%"><A href="http://forum.javaeye.com/viewtopic.php?p=105482#105482"><IMG title=文章 height=9 alt=文章 src="http://forum.javaeye.com/templates/subSilver/images/icon_minipost.gif" width=12 border=0></A><SPAN class=postdetails>时间: 2005-12-14 10:22:24<SPAN class=gen>&nbsp;</SPAN>&nbsp; &nbsp;标题: </SPAN></TD>
<TD vAlign=top noWrap><A href="http://forum.javaeye.com/posting.php?mode=quote&amp;p=105482"><IMG title=引用回复 alt=引用回复 src="http://forum.javaeye.com/templates/subSilver/images/lang_chinese_simplified/icon_quote.gif" border=0></A> <A href="http://forum.javaeye.com/addblog.php?type=javaeye&amp;title=OpenSessionInView会不会影响性能？&amp;t=17501&amp;postdays=0&amp;postorder=asc&amp;start=0&amp;p=105482"><IMG title=将这个帖子加入我的Blog alt=将这个帖子加入我的Blog src="http://forum.javaeye.com/templates/subSilver/images/icon_blog.gif" border=0></A></TD></TR>
<TR>
<TD colSpan=2>
<HR>
</TD></TR>
<TR>
<TD colSpan=2><SPAN class=postbody></SPAN>
<TABLE cellSpacing=1 cellPadding=3 width="90%" align=center border=0>
<TBODY>
<TR>
<TD><SPAN class=genmed><B>引用:</B></SPAN></TD></TR>
<TR>
<TD class=quote>因此，OpenSessionInView虽然确实方便，但是大家还是慎用吧。对于那些页面渲染速度很慢，拨号连接用户数量过多的网站就最好不要使用。</TD></TR></TBODY></TABLE><SPAN class=postbody><BR>确切的应该是大并发用户量的情况吧。这个问题一直都存在，在1年多前我和robbin争论中就提出来了过。hibernate2的代码可以看到session是和connection紧密耦合的（Hibernate3没看过）。但hibernate大部分被用于并发用户可预见的intranet应用，所以问题也不是很大。如果并发用户多，对connection pool资源, opensession in view在hibernate中使用会构成较大压力。如果jboss j2ee5 server采用hibernate作为ejb3实现，没有做修正的话，同样的问题也会存在于jboss j2ee5 server中。</SPAN><SPAN class=postbody></SPAN><SPAN class=gensmall><BR><BR>上一次由Charlesxp于2005-12-14 周三, 上午10:25修改，总共修改了2次</SPAN></TD></TR></TBODY></TABLE>
<TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR>
<TD width="100%"><A href="http://forum.javaeye.com/viewtopic.php?p=105483#105483"><IMG title=文章 height=9 alt=文章 src="http://forum.javaeye.com/templates/subSilver/images/icon_minipost.gif" width=12 border=0></A><SPAN class=postdetails>时间: 2005-12-14 10:22:33<SPAN class=gen>&nbsp;</SPAN>&nbsp; &nbsp;标题: </SPAN></TD>
<TD vAlign=top noWrap><A href="http://forum.javaeye.com/posting.php?mode=quote&amp;p=105483"><IMG title=引用回复 alt=引用回复 src="http://forum.javaeye.com/templates/subSilver/images/lang_chinese_simplified/icon_quote.gif" border=0></A> <A href="http://forum.javaeye.com/addblog.php?type=javaeye&amp;title=OpenSessionInView会不会影响性能？&amp;t=17501&amp;postdays=0&amp;postorder=asc&amp;start=0&amp;p=105483"><IMG title=将这个帖子加入我的Blog alt=将这个帖子加入我的Blog src="http://forum.javaeye.com/templates/subSilver/images/icon_blog.gif" border=0></A></TD></TR>
<TR>
<TD colSpan=2>
<HR>
</TD></TR>
<TR>
<TD colSpan=2><SPAN class=postbody></SPAN>
<TABLE cellSpacing=1 cellPadding=3 width="90%" align=center border=0>
<TBODY>
<TR>
<TD><SPAN class=genmed><B>hongliang 写道:</B></SPAN></TD></TR>
<TR>
<TD class=quote>几天没来，居然变精华叻。。。本来我也想做一下robbin的那个测试，结果这几天忙于其它事，一直没时间。看来OpenSessionInView果然有这个问题，这也是我一直担心的，看来真是应叻那句话，“如果一件事可能出错，那它一定会出错”。。。 <BR><BR>不过，如果不用OpenSessionInView，我还真一下子就找不到北叻，从学Hibernate开始就一直在OpenSessionInView的熏陶下长大。。。-_-b <BR><BR>Robbin有什么好的办法能够在不使用OpenSessionInView的情况下比较好的处理页面吗？</TD></TR></TBODY></TABLE><SPAN class=postbody><BR><BR>在dao中对要render的集合强制初始化。</SPAN><SPAN class=postbody></SPAN><SPAN class=gensmall></SPAN></TD></TR></TBODY></TABLE>
<TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR>
<TD width="100%"><A href="http://forum.javaeye.com/viewtopic.php?p=105503#105503"><IMG title=文章 height=9 alt=文章 src="http://forum.javaeye.com/templates/subSilver/images/icon_minipost.gif" width=12 border=0></A><SPAN class=postdetails>时间: 2005-12-14 10:51:52<SPAN class=gen>&nbsp;</SPAN>&nbsp; &nbsp;标题: </SPAN></TD>
<TD vAlign=top noWrap><A href="http://forum.javaeye.com/posting.php?mode=quote&amp;p=105503"><IMG title=引用回复 alt=引用回复 src="http://forum.javaeye.com/templates/subSilver/images/lang_chinese_simplified/icon_quote.gif" border=0></A> <A href="http://forum.javaeye.com/addblog.php?type=javaeye&amp;title=OpenSessionInView会不会影响性能？&amp;t=17501&amp;postdays=0&amp;postorder=asc&amp;start=15&amp;p=105503"><IMG title=将这个帖子加入我的Blog alt=将这个帖子加入我的Blog src="http://forum.javaeye.com/templates/subSilver/images/icon_blog.gif" border=0></A></TD></TR>
<TR>
<TD colSpan=2>
<HR>
</TD></TR>
<TR>
<TD colSpan=2><SPAN class=postbody></SPAN>
<TABLE cellSpacing=1 cellPadding=3 width="90%" align=center border=0>
<TBODY>
<TR>
<TD><SPAN class=genmed><B>hongliang 写道:</B></SPAN></TD></TR>
<TR>
<TD class=quote>是不是像这样？ <BR><BR>foo.getBars()</TD></TR></TBODY></TABLE><SPAN class=postbody><BR><BR>Hibernate.initialize(foo.getBars);</SPAN><SPAN class=postbody></SPAN><SPAN class=gensmall></SPAN></TD></TR></TBODY></TABLE><img src ="http://www.blogjava.net/TrampEagle/aggbug/30094.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/TrampEagle/" target="_blank">TrampEagle</a> 2006-02-10 09:52 <a href="http://www.blogjava.net/TrampEagle/articles/30094.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>一篇关于Spring AOP编程的教程</title><link>http://www.blogjava.net/TrampEagle/articles/27728.html</link><dc:creator>TrampEagle</dc:creator><author>TrampEagle</author><pubDate>Thu, 12 Jan 2006 04:45:00 GMT</pubDate><guid>http://www.blogjava.net/TrampEagle/articles/27728.html</guid><wfw:comment>http://www.blogjava.net/TrampEagle/comments/27728.html</wfw:comment><comments>http://www.blogjava.net/TrampEagle/articles/27728.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/TrampEagle/comments/commentRss/27728.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/TrampEagle/services/trackbacks/27728.html</trackback:ping><description><![CDATA[引自：<A href="http://spring.jactiongroup.net/viewtopic.php?t=478">http://spring.jactiongroup.net/viewtopic.php?t=478</A><BR><BR><SPAN class=postbody><FONT size=2>这是在网上发现的一篇关于Spring AOP编程的教程，读完这篇文章后，Spring AOP不再难以理解，因此我把它译成中文，推荐给Spring AOP的初学者。这是译文的</FONT><A class=postlink href="http://tools.devchannel.org/devtoolschannel/04/04/15/1457223.shtml" target=_blank><FONT color=#5493b4 size=2>链接</FONT></A><FONT size=2>。 <BR><BR>AOP正在成为软件开发的下一个圣杯。使用AOP，你可以将处理aspect的代码注入主程序，通常主程序的主要目的并不在于处理这些aspect。AOP可以防止代码混乱。 <BR>为了理解AOP如何做到这点，考虑一下记日志的工作。日志本身不太可能是你开发的主程序的主要任务。如果能将“不可见的”、通用的日志代码注入主程序中，那该多好啊。AOP可以帮助你做到。 <BR>Spring framework是很有前途的AOP技术。作为一种非侵略性的，轻型的AOP framework，你无需使用预编译器或其他的元标签，便可以在Java程序中使用它。这意味着开发团队里只需一人要对付AOP framework，其他人还是象往常一样编程。 <BR>AOP是很多直觉难以理解的术语的根源。幸运的是，你只要理解三个概念，就可以编写AOP模块。这三个概念是：advice，pointcut和advisor。advice是你想向别的程序内部不同的地方注入的代码。pointcut定义了需要注入advice的位置，通常是某个特定的类的一个public方法。advisor是pointcut和advice的装配器，是将advice注入主程序中预定义位置的代码。 <BR><BR>既然我们知道了需要使用advisor向主要代码中注入“不可见的”advice，让我们实现一个Spring AOP的例子。在这个例子中，我们将实现一个before advice，这意味着advice的代码在被调用的public方法开始前被执行。以下是这个before advice的实现代码： <BR><BR></FONT></SPAN>
<TABLE cellSpacing=1 cellPadding=3 width="90%" align=center border=0>
<TBODY>
<TR>
<TD><SPAN class=genmed><B><FONT size=2>代码:</FONT></B></SPAN></TD></TR>
<TR>
<TD class=code>package com.company.springaop.test; <BR><BR>import java.lang.reflect.Method; <BR>import org.springframework.aop.MethodBeforeAdvice; <BR><BR>public class TestBeforeAdvice implements MethodBeforeAdvice { <BR><BR>&nbsp; public void before(Method m, Object[] args, Object target) <BR>&nbsp; throws Throwable { <BR>&nbsp; &nbsp; System.out.println("Hello world! (by " <BR>&nbsp; &nbsp; &nbsp; &nbsp; + this.getClass().getName() <BR>&nbsp; &nbsp; &nbsp; &nbsp; + ")"); <BR>&nbsp; } <BR>} <BR>&nbsp;</TD></TR></TBODY></TABLE><SPAN class=postbody><BR><BR><FONT size=2>接口MethodBeforeAdvice只有一个方法before需要实现，它定义了advice的实现。before方法共用三个参数，它们提供了相当丰富的信息。参数Method m是advice开始后执行的方法。方法名称可以用作判断是否执行代码的条件。Object[] args是传给被调用的public方法的参数数组。当需要记日志时，参数args和被执行方法的名称，都是非常有用的信息。你也可以改变传给m的参数，但要小心使用这个功能；编写最初主程序的程序员并不知道主程序可能会和传入参数的发生冲突。Object target是执行方法m对象的引用。 <BR><BR>在下面的BeanImpl类中，每个public方法调用前，都会执行advice： <BR><BR></FONT></SPAN>
<TABLE cellSpacing=1 cellPadding=3 width="90%" align=center border=0>
<TBODY>
<TR>
<TD><SPAN class=genmed><B><FONT size=2>代码:</FONT></B></SPAN></TD></TR>
<TR>
<TD class=code>package com.company.springaop.test; <BR><BR>public class BeanImpl implements Bean { <BR><BR>&nbsp; public void theMethod() { <BR>&nbsp; &nbsp; System.out.println(this.getClass().getName() <BR>&nbsp; &nbsp; &nbsp; &nbsp; + "." + new Exception().getStackTrace()[0].getMethodName() <BR>&nbsp; &nbsp; &nbsp; &nbsp; + "()" <BR>&nbsp; &nbsp; &nbsp; &nbsp; + " says HELLO!"); <BR>&nbsp; } <BR>}</TD></TR></TBODY></TABLE><SPAN class=postbody><BR><BR><FONT size=2>类BeanImpl实现了下面的接口Bean： <BR><BR></FONT></SPAN>
<TABLE cellSpacing=1 cellPadding=3 width="90%" align=center border=0>
<TBODY>
<TR>
<TD><SPAN class=genmed><B><FONT size=2>代码:</FONT></B></SPAN></TD></TR>
<TR>
<TD class=code>package com.company.springaop.test; <BR><BR>public interface Bean { <BR>&nbsp; public void theMethod(); <BR>}</TD></TR></TBODY></TABLE><SPAN class=postbody><BR><BR><BR><FONT size=2>虽然不是必须使用接口，但面向接口而不是面向实现编程是良好的编程实践，Spring也鼓励这样做。 <BR><BR>pointcut和advice通过配置文件来实现，因此，接下来你只需编写主方法的Java代码： <BR></FONT></SPAN>
<TABLE cellSpacing=1 cellPadding=3 width="90%" align=center border=0>
<TBODY>
<TR>
<TD><SPAN class=genmed><B><FONT size=2>代码:</FONT></B></SPAN></TD></TR>
<TR>
<TD class=code><BR><BR>package com.company.springaop.test; <BR><BR>import org.springframework.context.ApplicationContext; <BR>import org.springframework.context.support.FileSystemXmlApplicationContext; <BR><BR>public class Main { <BR><BR>&nbsp; public static void main(String[] args) { <BR>&nbsp; &nbsp; //Read the configuration file <BR>&nbsp; &nbsp; ApplicationContext ctx <BR>&nbsp; &nbsp; &nbsp; &nbsp; = new FileSystemXmlApplicationContext("springconfig.xml"); <BR><BR>&nbsp; &nbsp; //Instantiate an object <BR>&nbsp; &nbsp; Bean x = (Bean) ctx.getBean("bean"); <BR><BR>&nbsp; &nbsp; //Execute the public method of the bean (the test) <BR>&nbsp; &nbsp; x.theMethod(); <BR>&nbsp; } <BR>}</TD></TR></TBODY></TABLE><SPAN class=postbody><BR><BR><BR><FONT size=2>我们从读入和处理配置文件开始，接下来马上要创建它。这个配置文件将作为粘合程序不同部分的“胶水”。读入和处理配置文件后，我们会得到一个创建工厂ctx。任何一个Spring管理的对象都必须通过这个工厂来创建。对象通过工厂创建后便可正常使用。 <BR><BR>仅仅用配置文件便可把程序的每一部分组装起来。 <BR></FONT></SPAN>
<TABLE cellSpacing=1 cellPadding=3 width="90%" align=center border=0>
<TBODY>
<TR>
<TD><SPAN class=genmed><B><FONT size=2>代码:</FONT></B></SPAN></TD></TR>
<TR>
<TD class=code><BR>&lt;?xml version="1.0" encoding="UTF-8"?&gt; <BR>&lt;!DOCTYPE beans PUBLIC&nbsp; "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"&gt; <BR><BR>&lt;beans&gt; <BR>&nbsp; &lt;!--CONFIG--&gt; <BR>&nbsp; &lt;bean id="bean" class="org.springframework.aop.framework.ProxyFactoryBean"&gt; <BR>&nbsp; &nbsp; &lt;property name="proxyInterfaces"&gt; <BR>&nbsp; &nbsp; &nbsp; &lt;value&gt;com.company.springaop.test.Bean&lt;/value&gt; <BR>&nbsp; &nbsp; &lt;/property&gt; <BR>&nbsp; &nbsp; &lt;property name="target"&gt; <BR>&nbsp; &nbsp; &nbsp; &lt;ref local="beanTarget"/&gt; <BR>&nbsp; &nbsp; &lt;/property&gt; <BR>&nbsp; &nbsp; &lt;property name="interceptorNames"&gt; <BR>&nbsp; &nbsp; &nbsp; &lt;list&gt; <BR>&nbsp; &nbsp; &nbsp; &nbsp; &lt;value&gt;theAdvisor&lt;/value&gt; <BR>&nbsp; &nbsp; &nbsp; &lt;/list&gt; <BR>&nbsp; &nbsp; &lt;/property&gt; <BR>&nbsp; &lt;/bean&gt; <BR><BR>&nbsp; &lt;!--CLASS--&gt; <BR>&nbsp; &lt;bean id="beanTarget" class="com.company.springaop.test.BeanImpl"/&gt; <BR><BR>&nbsp; &lt;!--ADVISOR--&gt; <BR>&nbsp; &lt;!--Note: An advisor assembles pointcut and advice--&gt; <BR>&nbsp; &lt;bean id="theAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor"&gt; <BR>&nbsp; &nbsp; &lt;property name="advice"&gt; <BR>&nbsp; &nbsp; &nbsp; &lt;ref local="theBeforeAdvice"/&gt; <BR>&nbsp; &nbsp; &lt;/property&gt; <BR>&nbsp; &nbsp; &lt;property name="pattern"&gt; <BR>&nbsp; &nbsp; &nbsp; &lt;value&gt;com\.company\.springaop\.test\.Bean\.theMethod&lt;/value&gt; <BR>&nbsp; &nbsp; &lt;/property&gt; <BR>&nbsp; &lt;/bean&gt; <BR><BR>&nbsp; &lt;!--ADVICE--&gt; <BR>&nbsp; &lt;bean id="theBeforeAdvice" class="com.company.springaop.test.TestBeforeAdvice"/&gt; <BR>&lt;/beans&gt; <BR>&nbsp;</TD></TR></TBODY></TABLE><SPAN class=postbody><BR><BR><FONT size=2>四个bean定义的次序并不重要。我们现在有了一个advice，一个包含了正则表达式pointcut的advisor，一个主程序类和一个配置好的接口，通过工厂ctx，这个接口返回自己本身实现的一个引用。 <BR><BR>BeanImpl和TestBeforeAdvice都是直接配置。我们用一个唯一的ID创建一个bean元素，并指定了一个实现类。这就是全部的工作。 <BR><BR>advisor通过Spring framework提供的一个RegexMethodPointcutAdvisor类来实现。我们用advisor的一个属性来指定它所需的advice-bean。第二个属性则用正则表达式定义了pointcut，确保良好的性能和易读性。 <BR><BR>最后配置的是bean，它可以通过一个工厂来创建。bean的定义看起来比实际上要复杂。bean是ProxyFactoryBean的一个实现，它是Spring framework的一部分。这个bean的行为通过一下的三个属性来定义： <BR><BR></FONT>
<UL><BR>
<LI>属性proxyInterface定义了接口类。 <BR>
<LI>属性target指向本地配置的一个bean，这个bean返回一个接口的实现。 <BR>
<LI>属性interceptorNames是唯一允许定义一个值列表的属性。这个列表包含所有需要在beanTarget上执行的advisor。注意，advisor列表的次序是非常重要的。 <BR></LI></UL><BR><BR><SPAN style="FONT-WEIGHT: bold">Spring工具</SPAN> <BR><BR>虽然你可以手工修改Ant构建脚本，但使用SpringUI（译注：SpringUI现在是Spring framework的一部分，并改名为spring-ide），使用Spring AOP变得很简单，只要点点鼠标即可。你可以把SpringUI安装成Eclipse的一个plug-in。然后，你只需在你的project上右击鼠标，并选择“add Spring Project Nature”。在project属性中，你可以在“Spring Project”下添加Spring配置文件。在编译前把下面的类库加入project：aopalliance.jar，commons-logging.jar，jakarta-oro-2.0.7.jar和spring.jar。运行程序时你会看到下面的信息： <BR><BR>... (logging information) <BR>Hello world! (by com.company.springaop.test.TestBeforeAdvice) <BR>com.company.springaop.test.BeanImpl.theMethod() says HELLO! <BR><BR><BR><SPAN style="FONT-WEIGHT: bold">优点和缺点</SPAN> <BR><BR>Spring比起其他的framework更有优势，因为除了AOP以外，它提供了更多别的功能。作为一个轻型framework，它在J2EE不同的部分都可以发挥作用。因此，即使不想使用Spring AOP，你可能还是想使用Spring。另一个优点是，Spring并不要求开发团队所有的人员都会用它。学习Spring应该从Spring reference的第一页开始。读了本文后，你应该可以更好地理解Spring reference了。Spring唯一的缺点是缺乏更多的文档，但它的mailing list是个很好的补充，而且会不断地出现更多的文档。</SPAN><SPAN class=gensmall><BR></SPAN><img src ="http://www.blogjava.net/TrampEagle/aggbug/27728.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/TrampEagle/" target="_blank">TrampEagle</a> 2006-01-12 12:45 <a href="http://www.blogjava.net/TrampEagle/articles/27728.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>