<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
  <channel>
    <title>Java论坛最新讨论 - JavaEye</title>
    <description>Java编程、Java Web开发、Java企业应用、Java设计模式、Java开源框架、Java应用服务器 <br/>
圈子: 
<a href="http://android.group.javaeye.com/" target="_blank">Android</a>
<a href="http://jbpm.group.javaeye.com/" target="_blank">JBPM</a>
<a href="http://jsfgroup.group.javaeye.com/" target="_blank">JSF</a>
<a href="http://seam.group.javaeye.com/" target="_blank">Seam</a>
<a href="http://tapestrying.group.javaeye.com/" target="_blank">Tapestry</a>
<a href="http://grails.group.javaeye.com" target="_blank">Groovy</a>
<a href="http://lucene-group.group.javaeye.com/" target="_blank">Lucene</a>
<a href="http://ecside.group.javaeye.com/" target="_blank">GT-Grid</a>

 - Java编程，Ruby编程，微软.net，AJAX，敏捷软件开发，综合软件技术</description>
    <link>http://www.javaeye.com</link>
    <language>UTF-8</language>
    <copyright>Copyright 2003-2008, JavaEye.com</copyright>
    <docs>http://blogs.law.harvard.edu/tech/rss</docs>
    <generator>JavaEye - 做最棒的软件开发交流社区</generator>
      <item>
        <title>项目开发心得1</title>
        <author>JavaEye网站</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://superloafer.javaeye.com">superloafer</a>&nbsp;
          链接：<a href="http://www.javaeye.com/topic/230895" style="color:red;">http://www.javaeye.com/topic/230895</a>&nbsp;
          发表时间: 2008年08月21日
          <br/>
          声明：本文系JavaEye网站发布的原创文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          刚刚工作不久，还没有开始从头到尾开发过一个项目，而是负责对一个开发到后期的项目进行维护和后期开发。本以为这些工作没有什么技术含量，比较枯燥，然而出我所料的是，经过两个多月的维护工作，却领会到了很多软件或项目开发领域中的学问，虽然这些东西的字眼和概念原来在大学的时候遇见过n多次，但是从来理解不了是怎么回事。<br />1.说说需求挖掘，定义和管理吧。我本来就是刚入行，觉得谈这些上流话题有点不自量力。不过在这里我倒也不打算去网上找些资料把有关需求的内容拿来啰嗦一顿，而是说说自己的体会，知识和经验都是慢慢体会和积累的嘛。这个项目负责开发的人不多，需求一直都是通过和客户之间电话会议来确定的，即客户那边有什么要求经过双方讨论确定再有开发人员实现，完了后再转给测试跑跑看有没有问题。这样一直快要到交付的前一个月，老板以为接下来的就是些简单活，就叫我这个新手去锻炼锻炼，顺便看看人家是怎么开发一个项目的。可是就这个时候，众多严重的问题出现了：因为系统即将要交付使用，客户多少会积极一点去试用。结果经常出现错误或者莫名其妙的故障。比如开发的时候当初压根就没有考虑到多用户的情况，所以整个系统的多个地方都只是以单个用户的方式来编写的，比如一个货品的数量在进入一个页面的时候就取出来缓存并显示，然后这个用户在这个页面上逗留了十来分钟，再对这个货品数量进行修改，如果只有一个用户在使用这个系统的话，数据永远都是一致的，没有问题。但是如果多用户的话，结果就可想而知了。这个项目的测试人员也只有一个，当然没有考虑到在多台机上试试系统运行情况。还有，对真正要试用该系统的用户的场景没有事先了解，所以开发人员照着惯用思维进行开发，结果当然是用户提出异议了。还有，在系统开发前期的时候，没有很好考察定义系统的平均或一般负载，性能要求之类的关键指标，即没有考虑到压力测试。用户那边系统后，发现到了快速大量输入数据时，系统会慢得不可使用。除了这些典型的问题之外，还有客户在快要交付前突然要大范围更改和添加需求，弄得我们手忙脚乱也完不成任务。具体情况就不在赘述了。这些经历给我的体会是：需求果然是很难作的，所以要花心思，动脑筋，甚至花体力去尽量做好（比如可以到客户公司去考察考察，呵呵，不知道这个想法实不实际，个人想法而已）。切记一种姿态就是，客户扔了一个需求过来，讨论讨论过了，然后动手，弄完叫客户大概看看，没事就OK了，而是要多Push客户那边多搞搞，不断跟进（好像客户大部分都不是很积极的，所以项目公司这边要积极和客户联络）。不然开发到后期出了前期没有发现的大问题再修改代价就很高了。<br /><br />2.第二个体会，可以说就是“切肤之痛”吧。写代码比较辛苦吧，看代码好像也很辛苦，但是看一些几乎没有注释且比较乱的代码，并且这些代码还比较多，会不会很辛苦呢？答案是肯定的！大学时候学的一门课程，叫项目管理。那时候学那门课觉得简直就是浪费时间，很难领会到一些要工作后才能领会的知识，好像学来没用。比如书上说，开发一个项目，一般开发时间只占20%-30%，其余都是维护时间。出来工作后才发现维护时间还真的是很长，如果在这段时间里，一直都是由系统开发的那帮人来维护，到也罢，反正代码写的怎么样，他们自己看。但是万一项目的开发人员离职或者调到别的项目组从而原来的项目叫别人去维护的时候，就会发现优良的编码习惯是多么重要啊。我有时候实在觉得摸不透，就去问原来开发这个系统的人，结果有时候他看了之后自个也不知道怎么回事，还责怪我这样写是有问题的，还不时误会是我写的代码。我心里说，原来你刚不理它一个半月就都会不记得啊，呵呵。这些经历给我的启发就是：写代码的时候，想想以后。该写注释的地方，就算简短，加两句以后别人维护起来也省 了好多脑细胞去想那段代码到底是干啥的。<br /><br />3.哎，太晚了，明天还要上班，有时间再加上。都是自个感受，写出来备个案。
          <br/>
          <span style="color:red;">
            <a href="http://tales.javaeye.com/topic/230895#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Thu, 21 Aug 2008 01:17:05 +0800</pubDate>
        <link>http://www.javaeye.com/topic/230895</link>
        <guid>http://www.javaeye.com/topic/230895</guid>
      </item>
      <item>
        <title>这样的设计可行么？</title>
        <author>JavaEye网站</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://ebinaini.javaeye.com">ebinaini</a>&nbsp;
          链接：<a href="http://www.javaeye.com/topic/228832" style="color:red;">http://www.javaeye.com/topic/228832</a>&nbsp;
          发表时间: 2008年08月17日
          <br/>
          声明：本文系JavaEye网站发布的原创文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          最近做个项目 遇到查询性能问题 设计完后 性能问题解决了 但是 总感觉有什么不对的地方<br /><br />我有4个信息表 一个是厂房信息表 一个是仓库信息表 一个是土地信息表 一个是需求信息表<br /><br />他们的信息都不一样所以需要分开建立表<br /><br />但是我在前台查询的时候 需要他们4个表的所有数据 这样就会很慢 应为我用的是hibernate <br /><br />所以后来我有建了一个总表 里面就存查询用的字段 每次插入这四个表种的任何一个 都需要往总表种插入一条主键相同的记录 这样查询问题解决了  但是其他问题又出现了 我需要删除 如果删除多个信息的时候 就会有问题 <br /><br />应为 我不想 在根据总表的类型再去查找 到底要取那个表去删，所以有没有更好的设计 能解决这个问题
          <br/>
          <span style="color:red;">
            <a href="http://tales.javaeye.com/topic/228832#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sun, 17 Aug 2008 02:32:51 +0800</pubDate>
        <link>http://www.javaeye.com/topic/228832</link>
        <guid>http://www.javaeye.com/topic/228832</guid>
      </item>
      <item>
        <title>这样的应用有必要Hibernate？</title>
        <author>JavaEye网站</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://hex.javaeye.com">sole</a>&nbsp;
          链接：<a href="http://www.javaeye.com/topic/229228" style="color:red;">http://www.javaeye.com/topic/229228</a>&nbsp;
          发表时间: 2008年08月18日
          <br/>
          声明：本文系JavaEye网站发布的原创文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          其实也就有三张简单的表；<br />数据量特别大，一个表中会产生有几十万，甚至几百万条记录；<br />更新，删除，插入操作非常频繁，一般都是批量进行的。<br /><br />公司其他技术人员说，hibernate自动ORM,有自带缓冲,数据库连接池，减少了很多工作。<br />其实公司没有一人hibernate了解的，只听说而已，现学现用。 <br /><br />我觉得很没必要。用hibernate没有一点优势。<br />对hibernate了解比较深入的，能谈谈您的意见吗？<br />谢谢all
          <br/>
          <span style="color:red;">
            <a href="http://tales.javaeye.com/topic/229228#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 18 Aug 2008 15:21:12 +0800</pubDate>
        <link>http://www.javaeye.com/topic/229228</link>
        <guid>http://www.javaeye.com/topic/229228</guid>
      </item>
      <item>
        <title>关于这样一个异构系统的设计，你有何高招</title>
        <author>JavaEye网站</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://yeshucheng.javaeye.com">yeshucheng</a>&nbsp;
          链接：<a href="http://www.javaeye.com/topic/230012" style="color:red;">http://www.javaeye.com/topic/230012</a>&nbsp;
          发表时间: 2008年08月19日
          <br/>
          声明：本文系JavaEye网站发布的原创文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          A系统是用JAVA写的WEB application，部署在Tomcat下。而且这个系统分布在全国近30个地区，他们各自在不相干扰基本就类似一个C/S结构的系统。（而且这套系统已经在使用）<br /><br />现在需要设计一套这样的系统：<br />要求B系统也是用JAVA来写的WEB-APPLICATION，它部署在WEBLOGIC中这套系统用来专门收集分散在全国多个地区A系统的数据（统计）和自身的其他一些功能，而且这些数据需要在B系统中尽可能的做到实时响应显示。经过分析B系统只关心A系统中一些关键的业务表。如果是你，你会如何设计这样一套B系统？
          <br/>
          <span style="color:red;">
            <a href="http://tales.javaeye.com/topic/230012#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Tue, 19 Aug 2008 07:31:36 +0800</pubDate>
        <link>http://www.javaeye.com/topic/230012</link>
        <guid>http://www.javaeye.com/topic/230012</guid>
      </item>
      <item>
        <title>一个新手提问，可能会挨骂的问题</title>
        <author>JavaEye网站</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://hanfengbeyond.javaeye.com">hanfengbeyond</a>&nbsp;
          链接：<a href="http://www.javaeye.com/topic/230886" style="color:red;">http://www.javaeye.com/topic/230886</a>&nbsp;
          发表时间: 2008年08月20日
          <br/>
          声明：本文系JavaEye网站发布的原创文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          一个比较差的问题，别骂我啊，我是实在解决不了了，本人天性愚钝，各位多帮忙吧。<br />在一个注册页面中，已经点击了下一步，突然用户发现不对了，他点回去，我现在想做的是，他点回去的时候能够保留他原来填写或是选择过得信息。就是这样，帮帮忙了，谢谢。
          <br/>
          <span style="color:red;">
            <a href="http://tales.javaeye.com/topic/230886#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Wed, 20 Aug 2008 23:41:55 +0800</pubDate>
        <link>http://www.javaeye.com/topic/230886</link>
        <guid>http://www.javaeye.com/topic/230886</guid>
      </item>
      <item>
        <title>ClassNotFoundException: org.hibernate.hql.ast.HqlT</title>
        <author>JavaEye网站</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://loforgood.javaeye.com">loforgood</a>&nbsp;
          链接：<a href="http://www.javaeye.com/topic/230882" style="color:red;">http://www.javaeye.com/topic/230882</a>&nbsp;
          发表时间: 2008年08月20日
          <br/>
          声明：本文系JavaEye网站发布的原创文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          我的项目架构是 Struts+spring+hibernate.在Tomcat中运行正常，然后部署到Weblogic8.1上报如上错误。<br /><br />原因：从网上获知，weblogic.jar中已经有了一个antlr.jar的版本，导致应用中hibernate3.jar中用到的antlr.jar不能找到，导致异常。<br /><br />解决方法：<br /><br /><br />可以按下面设置使用hibernate3的查询机制：<br />1、拷贝Hibernate3里带的包antlr-2.7.5H3.jar到%WL_HOME%\server\lib下<br />2、修改startWebLogic.cmd ：<br /><br />在set CLASSPATH之前加上下面一句：<br />set PRE_CLASSPATH=%WL_HOME%\server\lib\antlr-2.7.5H3.jar;<br />在set CLASSPATH之后加上下面一句：<br />set CLASSPATH=%PRE_CLASSPATH%;%CLASSPATH%
          <br/>
          <span style="color:red;">
            <a href="http://tales.javaeye.com/topic/230882#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Wed, 20 Aug 2008 23:19:19 +0800</pubDate>
        <link>http://www.javaeye.com/topic/230882</link>
        <guid>http://www.javaeye.com/topic/230882</guid>
      </item>
      <item>
        <title>一个A股迷你股票信息机——StockFX</title>
        <author>JavaEye网站</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://carl-kkx-hotmail-com.javaeye.com">carlkkx</a>&nbsp;
          链接：<a href="http://www.javaeye.com/topic/228447" style="color:red;">http://www.javaeye.com/topic/228447</a>&nbsp;
          发表时间: 2008年08月15日
          <br/>
          声明：本文系JavaEye网站发布的原创文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          最近两天搞了一个迷你股票信息机<br />大家用用看觉得如何。<br /><br />需要java1.6才能运行，因为表格排序用了java1.6中Swing的API
          <br/>
          <span style="color:red;">
            <a href="http://tales.javaeye.com/topic/228447#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Fri, 15 Aug 2008 16:45:09 +0800</pubDate>
        <link>http://www.javaeye.com/topic/228447</link>
        <guid>http://www.javaeye.com/topic/228447</guid>
      </item>
      <item>
        <title>我该如何设计这样的关系映射</title>
        <author>JavaEye网站</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://xudong82113.javaeye.com">xudong82113</a>&nbsp;
          链接：<a href="http://www.javaeye.com/topic/229145" style="color:red;">http://www.javaeye.com/topic/229145</a>&nbsp;
          发表时间: 2008年08月18日
          <br/>
          声明：本文系JavaEye网站发布的原创文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          需求非常简单。有一种实体叫做<strong>广告</strong>,广告有多种<strong>投放方式</strong>， 当然<strong>一次只会是一种</strong>。 <br />   简化的uml图如附件所示:<br /><br />   然而当我需要把它映射到数据库时却发现有很多问题。<br />   Delivery作为Ad的一部分， 是不应该独立存在的， 那么hibernate的Component应该是最合适的。然而Component无法处理继承(Delivery只是一个接口或抽象类)。<br />   那么退而求其次， 我也能接受one-to-one的映射， 因为一个Ad至多只有一个Delivery， 那么主键映射的one-to-one应该也是合适的。 然而如果采用了主键映射的one-to-one，因为有外键依赖， 我无法对Delivery进行更新。<br />如下:<br /><pre name="code" class="java">
Ad ad = new Ad();
Delivery d = new ProportionDelivery(ad, proportion);
ad.setDelivery(d);
session.merge(ad); //此处ok
Delivery other = new CountDelivery(ad, maxcount);
ad.setDelivery(other);
session.merge(ad); //此处失败， 因为新旧的Delivery主键会冲突
</pre><br />  那好， 我再退而求其次， 使用外键的one-to-one映射，发现如果设置Delivery对Ad的外键unique属性的话， 也会失败， 因为新旧的外键值一样， 因此unique索引也不能加。 取消掉unique索引， 让Delivery对Ad只是一个普通的many-to-one， 以上代码终于表面上成功。 <br />  然而看一眼数据库， 又会发现问题， 数据库中的delivery表中有2条记录， 指向同一个Ad。 也就是说<br /><pre name="code" class="java">
ad.setDelivery(other);
session.merge(ad);
</pre><br />时， 旧的Delivery d 不会自动进行删除。 <br />而one-to-one属性是没有delete-orphan的， 虽然很多人抱怨这一点(one-to-one只是一个one-to-many的特例而已， 为什么就不支持delete-orphan)， 但目前没有就是没有， 我又无法接受应用程序在设置other之前， 手动删除旧的delivery，也很难去使用aop的interceptor删除旧的delivery, 为了支持delete-orphan, 只好将Ad对Delivery的映射改为one-to-many， 只是由应用程序的get，set方法保证Ad里面的delivery集合至多只会有一个元素。 并且Delivery对Ad的many-to-one映射也不设置unique。<br />经过这么一番调整以后， 原来的代码终于正常运行， 数据库结果也和预想的一致。 但是这个OR-mapping绝非一开始预想的关系， 从component->one-to-one->one-to-many。<br />各位对于上面这个实例， 是否有更好的办法？
          <br/>
          <span style="color:red;">
            <a href="http://tales.javaeye.com/topic/229145#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 18 Aug 2008 12:30:14 +0800</pubDate>
        <link>http://www.javaeye.com/topic/229145</link>
        <guid>http://www.javaeye.com/topic/229145</guid>
      </item>
      <item>
        <title>公司要求实时监控服务器，写个Web的监控系统</title>
        <author>JavaEye网站</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://kakaluyi.javaeye.com">kakaluyi</a>&nbsp;
          链接：<a href="http://www.javaeye.com/topic/228636" style="color:red;">http://www.javaeye.com/topic/228636</a>&nbsp;
          发表时间: 2008年08月16日
          <br/>
          声明：本文系JavaEye网站发布的原创文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>&nbsp;</p>
<p>&nbsp;</p>
<p>公司的服务器需要实时监控，而且当用户空间已经满了，操作失败，或者出现程序Exception的时候就需要实时提醒，便于网管和程序员调式，这样就把这个实时监控系统分为了两部分，</p>
<p>&nbsp;</p>
<p>第一部分：实时系统监控（cpu利用率，cpu温度，总内存大小，已使用内存大小）</p>
<p>第二部分：实时告警</p>
<p>由于无刷新实时性，所以只能使用Ajax，这里没有用到任何ajax框架，因为调用比较简单</p>
<p>大家知道，由于java的先天不足，对底层系统的调用和操作一般用jni来完成，特别是cpu温度，你在window下是打死用命令行是得不到的，但由于我们的服务器系统是linux，所以可以不调用jni完全用java的方式来得到系统信息，这里用到了runtime的exec()函数，通过解析本地命令调用的结果来查询本地信息，</p>
<p>这里要感谢公司同事qinkun推荐ecsun兄的这篇文章<a href="http://papa.javaeye.com/blog/220532">http://papa.javaeye.com/blog/220532</a>，</p>
<p>&nbsp;</p>
<pre name="code" class="java">* 取得linux系统下的cpu、内存信息 
* 
* */ 
public final class LinuxSystemTool 
{ 
/** 
* get memory by used info 
* 
* @return int[] result 
* result.length==4;int[0]=MemTotal;int[1]=MemFree;int[2]=SwapTotal;int[3]=SwapFree; 
* @throws IOException 
* @throws InterruptedException 
*/ 
public static int[] getMemInfo() throws IOException, InterruptedException 
{ 
File file = new File("/proc/meminfo"); 
BufferedReader br = new BufferedReader(new InputStreamReader( 
new FileInputStream(file))); 
int[] result = new int[4]; 
String str = null; 
StringTokenizer token = null; 
while((str = br.readLine()) != null) 
{ 
token = new StringTokenizer(str); 
if(!token.hasMoreTokens()) 
continue; 

str = token.nextToken(); 
if(!token.hasMoreTokens()) 
continue; 

if(str.equalsIgnoreCase("MemTotal:")) 
result[0] = Integer.parseInt(token.nextToken()); 
else if(str.equalsIgnoreCase("MemFree:")) 
result[1] = Integer.parseInt(token.nextToken()); 
else if(str.equalsIgnoreCase("SwapTotal:")) 
result[2] = Integer.parseInt(token.nextToken()); 
else if(str.equalsIgnoreCase("SwapFree:")) 
result[3] = Integer.parseInt(token.nextToken()); 
} 

return result; 
} 

/** 
* get memory by used info 
* 
* @return float efficiency 
* @throws IOException 
* @throws InterruptedException 
*/ 
public static float getCpuInfo() throws IOException, InterruptedException 
{ 
File file = new File("/proc/stat"); 
BufferedReader br = new BufferedReader(new InputStreamReader( 
new FileInputStream(file))); 
StringTokenizer token = new StringTokenizer(br.readLine()); 
token.nextToken(); 
int user1 = Integer.parseInt(token.nextToken()); 
int nice1 = Integer.parseInt(token.nextToken()); 
int sys1 = Integer.parseInt(token.nextToken()); 
int idle1 = Integer.parseInt(token.nextToken()); 

Thread.sleep(1000); 

br = new BufferedReader( 
new InputStreamReader(new FileInputStream(file))); 
token = new StringTokenizer(br.readLine()); 
token.nextToken(); 
int user2 = Integer.parseInt(token.nextToken()); 
int nice2 = Integer.parseInt(token.nextToken()); 
int sys2 = Integer.parseInt(token.nextToken()); 
int idle2 = Integer.parseInt(token.nextToken()); 

return (float)((user2 + sys2 + nice2) - (user1 + sys1 + nice1)) / (float)((user2 + nice2 + sys2 + idle2) - (user1 + nice1 + sys1 + idle1)); 
} 
} 

</pre>
<p>&nbsp;</p>
<p>这里的两个方法，解释一下，</p>
<p>方法1文件"/proc/meminfo"里面包含的就是内存的信息，还包括了swap的信息。例如： <br /><br />$ cat /proc/meminfo <br /><br />total: used: free: shared: buffers: cached: <br />Mem: 1057009664 851668992 205340672 0 67616768 367820800 <br />Swap: 2146787328 164429824 1982357504 <br />MemTotal: 1032236 kB <br />MemFree: 200528 kB <br />MemShared: 0 kB <br />这样可以用截取字符串的方法，来得到linux内存信息.</p>
<p>方法2在文件"/proc/stat"里面就包含了CPU的信息。每一个CPU的每一tick用在什么地方都在这个文件里面记着。后面的数字含义分别是： user、nice、sys、idle、iowait。有些版本的kernel没有iowait这一项。这些数值表示从开机到现在，CPU的每tick用在了哪里。例如： <br /><br />cpu0 256279030 0 11832528 1637168262 <br /><br />就是cpu0从开机到现在有 256279030 tick用在了user消耗，11832528用在了sys消耗。所以如果想计算单位时间（例如1s）里面CPU的负载，那只需要计算1秒前后数值的差除以每一秒的tick数量就可以了。</p>
<p>ok这样还剩下cpu温度，怎么做呢</p>
<p>发现了一个文件"cat /proc/acpi/thermal_zone/THM/temperature";可以返回本机的linux温度，</p>
<p>大概是这样的：temperature：&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;68C</p>
<p>但不是每台linux机器都有这个THM你要确定你的linux加载了这个THM才能使用这个文件，这样就用<span style="color: #ff0000;">InputStreamReader(new FileInputStream（new File("/proc/acpi/thermal_zone/THM/temperature")）,</span>去读取这个文件，后面的相信大家一定会做了吧，就是把内容读出来,然后分割字符串去得到这个68。ok,系统基本信息全部完成，然后ok现在就只有一件事就是用Ajax去调用这个类来得到&nbsp;基本信息，然后返回到页面上，Ajax的用法就不赘言了。</p>
<p>&nbsp;</p>
<p>下面是系统监控的效果，大概是Ajax每几秒去linux下去取一次系统信息，然后显示在jsp页面上，以下是效果。</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;<img src="../../../../upload/picture/pic/19967/7c685f82-cfc3-365a-8d3b-1487f495530b.bmp?1218858196" height="204" alt="" width="450" /></p>
<p>&nbsp;</p>
<p>到这里第一部分系统监控部分已经完成，现在开始完成实时告警部分，分析需求</p>
<p>1温度和cpu超过额定值需要告警</p>
<p>2用户操作系统失败，用户存储空间不足也需要告警，还有我们公司的业务操作失败告警，如果发生Exception也只能告警，当然要把异常的堆栈的信息保存在数据库里，我就这样设计如果用户在操作中触发了这些错误，则保存在数据库的告警表里，然后实时监控的再取出来这些信息。</p>
<p>3告警是要实时的那么要怎么从告警表里查到当前以后的数据呢，一开始想到用当前时间，在当前时间加上Ajax发送时间间隔，select * from warnlist where date&gt;new Date()+AjaxTime这种形式,后来发现时间是很不正确的，网络延迟，程序处理时间，（cpu信息用了sleep函数），等等你常常会发现有些告警信息被无情的放过，而有的时候有重复数据，这样我想到了用id，每次进入告警系统先查询到最大的告警id,然后保存在session中，然后ajax从数据库里取告警信息的时候都查这个id之后的数据（就是进入监控系统后的最新数据），然后session再保存新的最大id,下次ajax取还是从这个session中取最大id,这样信息就可以当ajax取的时候都保证是最新的，而且没有重复，very good!就这样做了</p>
<p>这样设计了一张告警处理表</p>
<pre name="code" class="sql">CREATE TABLE `warnlist` (
  `Id` bigint(20) NOT NULL auto_increment,
  `warnleave` tinyint(2) NOT NULL default '0',//告警级别：告警的严重程度
  `fromguy` varchar(20) NOT NULL,//属于哪个用户哪个组织的告警
  `warncontent` varchar(100) NOT NULL,//告警内容，比如cpu使用率超过80%
  `aviliablevalue` varchar(12) default NULL,//允许值 比如85%
  `warnvalue` varchar(12) default NULL,//告警值 80
  `warntime` datetime NOT NULL,//告警时间
  `stackinfo` varchar(255) default NULL,//异常的堆栈信息
  `dealwith` tinyint(2) NOT NULL default '0',//处理结果
  `version` int(11) default NULL,//version
  `organizerID` varchar(20) default NULL,//组织id
  `des` varchar(255) default NULL,
  PRIMARY KEY  (`Id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;</pre>
<p>&nbsp;</p>
<p>假设我ajax从系统取信息后，那么要写个逻辑，if(cpuTempature&gt;75C)or if(cpuUserd&gt;80%)则写入数据库，然后再查询大于上一次发送Ajax数据库的最大id的告警信息（这期间如果发生的以下错误一并查出：用户存储空间不足，还有我们公司的业务操作失败告警，Exception等），循环插入一个xml解析类中，大概形式是这样的Ajax返回这个xml,供页面提取信息</p>
<pre name="code" class="xml">&lt;response&gt;
&lt;cpuUsed&gt;67&lt;/cpuUsed&gt;
&lt;cpuTemp&gt;76&lt;cpuTemp&gt;
&lt;Memory&gt;1023422&lt;/Memory&gt;
&lt;freeMemory&gt;43244&lt;/freeMemory&gt;
&lt;wannlist&gt;
&lt;warnid&gt;2&lt;/warnid&gt;
&lt;warncontent&gt;系统存储空间不足&lt;/warncontent&gt;
&lt;fromguy&gt;kakaluyi&lt;/fromguy&gt;
..............
&lt;/wanrlist&gt;
&lt;warnlist&gt;
&lt;warnid&gt;3&lt;/warnid&gt;
&lt;warncontent&gt;cpu温度过高&lt;/warncontent&gt;
&lt;fromguy&gt;系统&lt;/fromguy&gt;
&lt;orgid&gt;系统&lt;/orgid&gt;
&lt;warnvalue&gt;78&lt;/warnvalue&gt;
.............
&lt;/warnlist&gt;
........

&lt;/response&gt;</pre>
<p>&nbsp;</p>
<p>系统信息的显示代码，就是关联上面那个图片的：</p>
<pre name="code" class="html">var cpuUsed=req.responseXML.getElementsByTagName('cpuUsed')[0].firstChild.nodeValue;
var totalMemory=req.responseXML.getElementsByTagName('totalMemory')[0].firstChild.nodeValue;
var freeMemory=req.responseXML.getElementsByTagName('freeMemory')[0].firstChild.nodeValue;
var cpuTemp=req.responseXML.getElementsByTagName('cpuTemp')[0].firstChild.nodeValue;
$('cpuUsed').innerHTML=cpuUsed;
$('totalMemory').innerHTML=totalMemory;
$('freeMemory').innerHTML=freeMemory;
$('cpuTemp').innerHTML=cpuTemp;

//jsp
&lt;tr&gt;
&lt;td class="label" width="20%"&gt;
服务器CPU使用率：&lt;/td&gt;
&lt;td class="text"&gt;
&lt;font color="#FF0000" size="+2"&gt;&lt;label id="cpuUsed"&gt;&lt;/label&gt;
&lt;/font&gt; &lt; 告警预定阀值: 80% &gt;
&lt;/td&gt;
&lt;/tr&gt;
 .........</pre>
<p>然后就是页面展现的问题了这里我用了dom节点的增删，一个页面保持50条记录，如果超过50条则删除以前的节点，代码为：</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<pre name="code" class="js">var length=req.responseXML.getElementsByTagName('warnlist').length;
if(length&gt;0)
{
var trlength=document.getElementsByTagName('table')[4].childNodes[0].childNodes.length;

if(trlength+length-1&gt;50)//如果大于50条，则查找告警列表的table，得到
告警信息的子节点，然后删除多余的最早的告警信息
{
var tbody=document.getElementsByTagName('table')[4].childNodes[0];
for(var i=1;i&lt;trlength+length-50;i++)
{
var tr=tbody.childNodes[i];
tr.parentNode.removeChild(tr);

}</pre>
<p>&nbsp;</p>
<p>然后插入新的告警信息，</p>
<pre name="code" class="js">for(var i=0;i&lt;length;i++)
{
var onewarnlist=req.responseXML.getElementsByTagName('warnlist')[i].childNodes;
if(onewarnlist[0].firstChild.nodeValue==0)
{
var leave="企业级告警";
}
else {
var leave="运营商级告警";
}
var from=onewarnlist[1].firstChild.nodeValue;
var warncontent=onewarnlist[2].firstChild.nodeValue;
var aviliablevalue=onewarnlist[3].firstChild.nodeValue;
var warnvalue=onewarnlist[4].firstChild.nodeValue;
var warntime=onewarnlist[5].firstChild.nodeValue;
var id=onewarnlist[8].firstChild.nodeValue;
if(onewarnlist[6].firstChild.nodeValue==0)
{
var dealwith="未处理" ;
}
else {
var dealwith="&lt;font color='red'&gt;已处理&lt;/font&gt;";
}
var table=document.getElementById('warntable');
var tr=document.createElement('tr');
 if(x%2==1)
{
tr.style.backgroundColor="#BFD3F9"
}
else{
tr.style.backgroundColor="#FBFCEB"
}
x++;
table.appendChild(tr);
var td=document.createElement('td');
td.className ='listText';
td.innerHTML =x;
tr.appendChild(td);
var td1=document.createElement('td');
td1.className ='listText';
td1.innerHTML = leave;
tr.appendChild(td1);
var td2=document.createElement('td');
td2.className ='listText';
td2.innerHTML = from;
tr.appendChild(td2);
var td3=document.createElement('td');
td3.className ='listText';
td3.innerHTML = warncontent;
tr.appendChild(td3);6
var td4=document.createElement('td');
td4.className ='listText';
td4.innerHTML = aviliablevalue;
tr.appendChild(td4);
var td5=document.createElement('td');
td5.className ='listText';
td5.innerHTML = '&lt;font color="#FF0000"&gt;'+warnvalue+'&lt;/font&gt;';
tr.appendChild(td5);
var td6=document.createElement('td');
td6.className ='listText';
td6.innerHTML = warntime;
tr.appendChild(td6);
var td7=document.createElement('td');
td7.className ='listText';
td7.innerHTML = dealwith;
tr.appendChild(td7);
var td8=document.createElement('td');
td8.className ='listText';
td8.innerHTML = id;
tr.appendChild(td8);
   }</pre>
<p>&nbsp;</p>
<p>ok，一切大功告成，以下是最终效果</p>
<p><img src="../../../../upload/picture/pic/19963/89cd061e-0d44-31d6-8769-c69a06de7ae2.bmp?1218855651" height="343" alt="" width="762" /></p>
          <br/>
          <span style="color:red;">
            <a href="http://tales.javaeye.com/topic/228636#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sat, 16 Aug 2008 12:38:02 +0800</pubDate>
        <link>http://www.javaeye.com/topic/228636</link>
        <guid>http://www.javaeye.com/topic/228636</guid>
      </item>
      <item>
        <title>请点评jdbc通用访问方法，这样可行吗？</title>
        <author>JavaEye网站</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://hgq0011.javaeye.com">hgq0011</a>&nbsp;
          链接：<a href="http://www.javaeye.com/topic/230738" style="color:red;">http://www.javaeye.com/topic/230738</a>&nbsp;
          发表时间: 2008年08月20日
          <br/>
          声明：本文系JavaEye网站发布的原创文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          最近在检查其他同事写的代码，看到一同学写的了一个通用JDBC模板（静态工厂模式），似乎没有什么问题，但看起来很是不美观，有点怪异的感觉。我想了很久是不是要在论坛中发布，我觉得这样的代码还是不够OO，为什么自己对应的域对象操作不直接用用对象封装来处理呢？而转用ResultSetMetaData来解析对应的字段的属性，而且每次要把相关的参数保存到MAP、list中，然后又要取出来解析。所以我觉得回影响性能。当然在测试过程中没有发现性能的问题。由于项目中其他同学也在用他这个模板，他们觉得很方便。但对应新人（刚毕业的同学）来说，经常在调试的时候发生了错误，都不知错误发生在那？导致又要其他同学帮忙，乱费太多时间，而且他们还是不知其所以然。请大家帮忙评点一下。谢谢！<br /><pre name="code" class="java">
//通过SQL反回对应的数据集
//比如:sql select nameSc,age from users
public List getResultDataList(String sql, Connection con) {
		List&lt;Map> dataList = new ArrayList&lt;Map>();
		Map&lt;String, String> map = new HashMap&lt;String, String>();//存放对应字段数据
		PreparedStatement ps = null;
		ResultSet ds = null;
		ResultSetMetaData rsd;
		try {
			ps = con.prepareStatement(sql);
			ds = ps.executeQuery();
			while (ds.next()) {
				map = new HashMap&lt;String, String>();//通过键值对存放一条记录的数据
				rsd = ds.getMetaData();
				for (int i = 1; i &lt;= rsd.getColumnCount(); i++) {
					switch (rsd.getColumnType(i)) {//通过判断数据类型转换数据
					case 12:// varchar(12)
						map.put(rsd.getColumnName(i), ds.getString(i));
						break;
					case 1:// char(1)
						map.put(rsd.getColumnName(i), ds.getString(i));
						break;
					case -7:// bit(-7)
						map.put(rsd.getColumnName(i), Boolean.toString(ds
								.getBoolean(i)));
						break;
					case 4:// int(4)
						map.put(rsd.getColumnName(i), Integer.toString(ds
								.getInt(i)));
						break;
					case 5:// smallint(5)
						map.put(rsd.getColumnName(i), Integer.toString(ds
								.getInt(i)));
						break;	
					case 93:// datetime(93)
						if (ds.getString(i) == null)
							map.put(rsd.getColumnName(i), "");
						else {
							if (ds.getString(i).length() >= 19) {
								map.put(rsd.getColumnName(i), ds.getString(i)
										.substring(0, 19));
							} else {
								map.put(rsd.getColumnName(i), ds.getString(i)
										.substring(0, 10));
							}
						}
						break;
					case 3:// decimal(3)
						map.put(rsd.getColumnName(i), Double.toString(ds
								.getDouble(i)));
						break;
					default:
						map.put(rsd.getColumnName(i), ds.getString(i));
						break;
					}
				}
				dataList.add( map);//存放所有行数据
			}
		} catch (SQLException e) {
			e.printStackTrace();
			throw new RuntimeException(e);
		} finally {
                        <span style="color: red">connection是通过HibernateDaoSupport获取得到的，似乎能够自动回收（反回到连接池），是否真的不用关闭连接呢？</span>
			/*
			 * try{ if(ds!=null){ds.close();ds=null;}
			 * if(ps!=null){ps.close();ps=null;}
			 * if(con!=null){con.close();con=null;} }catch(SQLException e){}
			 */
		}
		return dataList;
	}
</pre><br /><br /><br /><pre name="code" class="java">
//通过传递SQL,Sql的参数更新数据
//比如 sql insert into users(nameCs,age)valuse(?,?)
//params就是存放?代表的值
public int execUpdateByParams(String sql, Connection con, List params) {
		PreparedStatement ps = null;
		int message = 0;
		try {
			String paramsStr="";
			ps = con.prepareStatement(sql);
			if (params != null) {
				for (int i = 0; i &lt; params.size(); i++) {
					String p = params.get(i)==null?null:"" + params.get(i);//设置对应的参数
					ps.setString(i + 1, p);
				}
			}
			ps.executeUpdate();
		} catch (SQLException e) {
			e.printStackTrace();
			message = -1;
			throw new RuntimeException(e);
		} finally {
			try {
				if (ps != null) {
					<span style="color: red">ps.close();</span>//怎么在这他有把这个关闭了呢？这会有问题吧？
					ps = null;
				}
				// if(con!=null){con.close();con=null;}
			} catch (SQLException e) {
			}
		}

		return message;
	}
</pre>
          <br/>
          <span style="color:red;">
            <a href="http://tales.javaeye.com/topic/230738#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Wed, 20 Aug 2008 16:04:30 +0800</pubDate>
        <link>http://www.javaeye.com/topic/230738</link>
        <guid>http://www.javaeye.com/topic/230738</guid>
      </item>
      <item>
        <title>JAVA与C#之间传递数据用什么格式</title>
        <author>JavaEye网站</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://jcs7575.javaeye.com">jcs7575</a>&nbsp;
          链接：<a href="http://www.javaeye.com/topic/228453" style="color:red;">http://www.javaeye.com/topic/228453</a>&nbsp;
          发表时间: 2008年08月15日
          <br/>
          声明：本文系JavaEye网站发布的原创文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          C#做前台<br />JAVA做后台<br />Weblogic做中间件<br /><br />现在的做法是收集前台的数据经过处理作成一个xml格式的String<br />通过weblogic传入到JAVA端 再解析成List。<br /><br />数据量小的时候没有什么问题，但是数据量大的时候就很慢了。<br /><br /><br />想问的是有没有别的通讯格式可以用？<br />感觉C#和java两端都用循环来处理数据不是很好，但又想不出什么办法。
          <br/>
          <span style="color:red;">
            <a href="http://tales.javaeye.com/topic/228453#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Fri, 15 Aug 2008 16:54:39 +0800</pubDate>
        <link>http://www.javaeye.com/topic/228453</link>
        <guid>http://www.javaeye.com/topic/228453</guid>
      </item>
      <item>
        <title>初手配置Tomcat6.0 + ActiveMq5.1 + Spring2.5</title>
        <author>JavaEye网站</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://kenshinhu.javaeye.com">kenshinhu</a>&nbsp;
          链接：<a href="http://www.javaeye.com/topic/229049" style="color:red;">http://www.javaeye.com/topic/229049</a>&nbsp;
          发表时间: 2008年08月17日
          <br/>
          声明：本文系JavaEye网站发布的原创文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p style="text-align: justify;"><span style="font-size: medium;">　<span style="font-size: small;">　<img src="../../images/smiles/icon_sad.gif" alt="" />
这个用了很多的时间都搞得成功，参考了不同的书籍，最后都成功了，在这里我把我的心得在这里写写</span>
</span>
</p>
<p style="text-align: justify;"><span style="font-size: small;">&nbsp;&nbsp;&nbsp;&nbsp; 首先，下载ActiveMq5.1，大家可以在官方网站下载：当大家下载解压后，就将文件夹的的包ＣＯＰＹ到web project下的lib文件夹里，需要拷贝的以下图的包(j2ee和jre除外)<br />
</span>
</p>
<p style="text-align: justify;">&nbsp;</p>
<p style="text-align: center;"><img src="../../../upload/attachment/35152/27608b6b-5a1b-31ff-8118-846a1bc6849c.jpg" height="241" alt="" width="316" />
</p>
<p><span style="font-size: small;">好了，现在开始写配置文件了。在src文件夹下新建一spring配置文件名为：applicationContext.xml。其代码如下：</span>
</p>
<pre name="code" class="xml">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;beans xmlns=&quot;http://www.springframework.org/schema/beans&quot;
	xmlns:amq=&quot;http://activemq.apache.org/schema/core&quot;
	xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
	xsi:schemaLocation=&quot;http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
  http://activemq.apache.org/schema/core http://activemq.apache.org/schema/core/activemq-core.xsd&quot;&gt;

	&lt;bean id=&quot;jmsConnectionFactory&quot;
		class=&quot;org.springframework.jndi.JndiObjectFactoryBean&quot;&gt;
		&lt;property name=&quot;jndiName&quot; value=&quot;java:comp/env/jms/ConnectionFactory&quot;&gt;&lt;/property&gt;
	&lt;/bean&gt;

	&lt;bean id=&quot;jmsQueue&quot;
		class=&quot;org.springframework.jndi.JndiObjectFactoryBean&quot;&gt;
		&lt;property name=&quot;jndiName&quot; value=&quot;java:comp/env/jms/Queue&quot;&gt;&lt;/property&gt;
	&lt;/bean&gt;

	&lt;bean id=&quot;jmsTemplate&quot;
		class=&quot;org.springframework.jms.core.JmsTemplate&quot;&gt;
		&lt;property name=&quot;connectionFactory&quot; ref=&quot;jmsConnectionFactory&quot;&gt;&lt;/property&gt;
		&lt;property name=&quot;defaultDestination&quot; ref=&quot;jmsQueue&quot;&gt;&lt;/property&gt;
	&lt;/bean&gt;

	&lt;bean id=&quot;sender&quot; class=&quot;message.Sender&quot;&gt;
		&lt;property name=&quot;jmsTemplate&quot; ref=&quot;jmsTemplate&quot;&gt;&lt;/property&gt;
	&lt;/bean&gt;

	&lt;bean id=&quot;receive&quot; class=&quot;message.Receiver&quot;&gt;&lt;/bean&gt;
	&lt;bean id=&quot;listenerContainer&quot;
		class=&quot;org.springframework.jms.listener.DefaultMessageListenerContainer&quot;&gt;
		&lt;property name=&quot;connectionFactory&quot; ref=&quot;jmsConnectionFactory&quot;&gt;&lt;/property&gt;
		&lt;property name=&quot;destination&quot; ref=&quot;jmsQueue&quot;&gt;&lt;/property&gt;
		&lt;property name=&quot;messageListener&quot; ref=&quot;receive&quot;&gt;&lt;/property&gt;
	&lt;/bean&gt;


&lt;/beans&gt;</pre>
<p>&nbsp;</p>
<p>这里中，其中就有一个地方花了我很多时间找资料。这里是用了ActiveMq的方式来配置Spring的配置文件，其中引入了xsd的文件。</p>
<pre name="code" class="xml">&lt;beans xmlns=&quot;http://www.springframework.org/schema/beans&quot;
	xmlns:amq=&quot;http://activemq.apache.org/schema/core&quot;
	xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
	xsi:schemaLocation=&quot;http://www.springframework.org/schema/beans 
               http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
               http://activemq.apache.org/schema/core 
               http://activemq.apache.org/schema/core/activemq-core.xsd&quot;&gt;

...................

&lt;beans&gt;</pre>
<p>&nbsp;
由于面的配置文件中使用了jndi，所以也得在Tomcat目录下的conf/context.xml配置,需加入</p>
<pre name="code" class="xml">&lt;Resource name=&quot;jms/ConnectionFactory&quot; 
  auth=&quot;Container&quot;   
  type=&quot;org.apache.activemq.ActiveMQConnectionFactory&quot; 
  description=&quot;JMS Connection Factory&quot;
  factory=&quot;org.apache.activemq.jndi.JNDIReferenceFactory&quot; 
  brokerURL=&quot;vm://localhost&quot; 
  brokerName=&quot;LocalActiveMQBroker&quot;/&gt;
 
&lt;Resource name=&quot;jms/Queue&quot; 
auth=&quot;Container&quot; 
type=&quot;org.apache.activemq.command.ActiveMQQueue&quot;
description=&quot;my Queue&quot;
factory=&quot;org.apache.activemq.jndi.JNDIReferenceFactory&quot; 
physicalName=&quot;FOO.BAR&quot;/&gt;</pre>
<p>&nbsp;在这里我分别配置了jmsConnectionFactory和jms点对点</p>
<p>&nbsp; 之后，就由消息生产者的代码</p>
<pre name="code" class="java">package message;

import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.Session;

import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.core.MessageCreator;


public class Sender {

	private JmsTemplate jmsTemplate;

	public void setJmsTemplate(JmsTemplate jmsTemplate) {
		this.jmsTemplate = jmsTemplate;
	}
	
	public void send(final String text){
		System.out.println(&quot;---Send:&quot;+text);
		jmsTemplate.send(new MessageCreator(){

			public Message createMessage(Session arg0) throws JMSException {
				// TODO Auto-generated method stub
				return arg0.createTextMessage(text);
			}
			
		});
	}

}
</pre>
&nbsp;
<p>消息接收者</p>
<pre name="code" class="java">package message;

import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage;

public class Receiver implements MessageListener {

	public void onMessage(Message message) {
		if (message instanceof TextMessage) {
			TextMessage text = (TextMessage) message;

			try {
				System.out.println(&quot;Receive:&quot; + text.getText());
			} catch (JMSException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

		}
	}
}
</pre>
&nbsp;
<p>这里分别帖了最简单的JMS配置，希望对初入门的有用。</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
          <br/>
          <span style="color:red;">
            <a href="http://tales.javaeye.com/topic/229049#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sun, 17 Aug 2008 23:50:20 +0800</pubDate>
        <link>http://www.javaeye.com/topic/229049</link>
        <guid>http://www.javaeye.com/topic/229049</guid>
      </item>
      <item>
        <title>DAO设计问题</title>
        <author>JavaEye网站</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://withmemores.javaeye.com">WithMemores</a>&nbsp;
          链接：<a href="http://www.javaeye.com/topic/229084" style="color:red;">http://www.javaeye.com/topic/229084</a>&nbsp;
          发表时间: 2008年08月18日
          <br/>
          声明：本文系JavaEye网站发布的原创文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          最近由于项目限制使用JDK1.4（没有办放使用泛型DAO）所以设计了一个DAO如下<br /><br /><pre name="code" class="java">
public interface Dao {
	public abstract List getList(int first,int max) throws Exception;
	public abstract int getTotal()throws Exception;
}

public abstract class AbsDao extends HibernateDaoSupport implements Dao {
	
	/**
	 *@return List 以集合形式返回符合HQL语句中实体 
	 *@param int max 最大记录数
	 *@param int first 第一条记录的位置
	 */
	public List getList(final int first,final int max)throws Exception{
		
		return super.getHibernateTemplate().executeFind(
			new HibernateCallback(){
				public Object doInHibernate(Session session) throws HibernateException,SQLException{
					try{
						return session.createQuery("from "+getTableName()).setFirstResult(first).setMaxResults(max).list();
					}
					catch(Exception e){
						throw new HibernateException(e);
					}
				}
			}
		); 
	}
	
	/**
	 * @return int count 返回HQL查询的记录数
	 * @param String HQL 统计的HQL语句
	*/
	public int getTotal() throws Exception {
		return ((Integer)super.getSession().createQuery("select count(*) from "+getTableName()).uniqueResult()).intValue();
	}
	
	/**
	 * @return String TableName
	 * */
	private String getTableName()throws Exception{
		return this.getClass().getName().substring(this.getClass().getName().lastIndexOf(".")+1, this.getClass().getName().length()-3);
	}
}


///这个是工具生成的修改了继承，使得为分页作准备。
public class UserinfoDAO extends AbsDao {}


//这个是伪泛型的DAO
public class DaoImpl extends AbsDao{
	/**
	 *@return List 以集合形式返回符合HQL语句中实体 
	 *@param String HQL  要执行的HQL语句
	 */
	public List getList(String HQL)throws Exception{
		return super.getHibernateTemplate().find(HQL);
	}
	
	/**
	 *将Object写入数据库 
	 *@param Object o  要保存的对象
	 */
	public void save(Object o)throws Exception{
		super.getHibernateTemplate().save(o);
	}
	
	/**
	 *将List(Object)写入数据库 
	 *@param List list(Object)  要保存的对象数组列表
	 */
	public void saveAll(List list)throws Exception{
		super.getHibernateTemplate().save(list);
	}
	
	/**
	 *将Object更新 
	 *@param Object o  要跟新的对象
	 */
	public void update(Object o)throws Exception{
		super.getHibernateTemplate().update(o);
	}
	
	
	/**
	 *将Object更新 
	 *@param List list(Object)  要更新的对象数组列表
	 */
	public void updateAll(List list)throws Exception{
		super.getHibernateTemplate().update(list);
	}
	

	/**通过SQL语句直接操作数据库
	 * @param String HQL;
	*/
	public void excuteSQL(String HQL) throws Exception {
		super.getHibernateTemplate().find(HQL);
	}

}

</pre><br /><br />服务层<br /><pre name="code" class="java">
public interface PageService{
	public abstract int getPageSize()throws Exception;
	public abstract void setPageSize(int pageSize)throws Exception;

	public abstract int getTotal() throws Exception;
	public abstract int getPageCount()throws Exception;
	public abstract List getFirstPage() throws Exception;
	public abstract List getLastPage() throws Exception;
	public abstract List getPreviousPage(int currentPage)throws Exception;
	public abstract List getNextPage(int currentPage)throws Exception;
	public abstract List getPointPage(int pointPage)throws Exception;

}

public abstract class AbsPageService implements PageService {
	/**
	 * @return int 数据库中记录总数
	 * */
	public int getTotal() throws Exception {
		return getDao().getTotal();
	}
	
	/**
	 *@return int totalpage 返回分页数 
	 *@param int PageSize 页面的记录数
	 */
	public int getPageCount(int PageSize) throws Exception {
		return ((getTotal()+PageSize)-1)/PageSize;
	}

	/**
	 *@return List 返回指定页面的记录  注意这个方法提供给接口方法
	 *@param int PointPage 指定的页面
	 *@param int PageSize 页面的记录数
	 */
	public List getPointPage(int PointPage, int PageSize) throws Exception {
		if(PointPage>=0&&PointPage&lt;=getPageCount(PageSize)){
			return getDao().getList((PointPage-1)*PageSize, PageSize);
		}
		else{
			return null;
		}
	}
	
	//以下是接口方法
	/**
	 *@return List 返回第一页的记录
	 **/
	public List getFirstPage() throws Exception{
		return this.getPointPage(1, PageSize);
	}
	
	/**
	 * @return List 返回最后一页
	 * */
	public List getLastPage() throws Exception{
		return this.getPointPage(this.getPageCount(PageSize), PageSize);
	}
	
	/**
	 * @return List 返回前一页的数据
	 * @param int currentPage 当前页
	 * */
	public List getPreviousPage(int currentPage)throws Exception{
		if(currentPage>1&&this.getTotal()>currentPage){
			return this.getPointPage(currentPage-1, PageSize);
		}
		else{
			return null;
		}
	}
	
	/**
	 * @return List 返回后一页的数据
	 * @param int currentPage 当前页
	 * */
	public List getNextPage(int currentPage)throws Exception{
		if(this.getTotal()>=(currentPage+1)&&(currentPage+1)>0){
			return this.getPointPage(currentPage+1, PageSize);
		}
		else{
			return null;
		}
	}
	
	/**
	 * @return List 返回当前页的数据
	 * @param int currentPage 当前页
	 * */
	public List getPointPage(int pointPage)throws Exception{
		if(this.getTotal()>=(pointPage)&&(pointPage)>0){
			return this.getPointPage(pointPage, PageSize);
		}
		else{
			return null;
		}
	}
	
	/**
	 * @return int 总页面数
	 * */
	public int getPageCount() throws Exception {
		return this.getPageCount(this.getPageSize());
	}
	//注入方法
	public int getPageSize() {
		return PageSize;
	}

	public void setPageSize(int pageSize) {
		PageSize = pageSize;
	}
	
	public Dao getDao() {
		return dao;
	}

	public void setDao(Dao dao) {
		this.dao = dao;
	}
	
	private int PageSize=10;
	private Dao dao;
}

public interface UserinfoService {
	public abstract void regist(Userinfo ui)throws Exception;
	public abstract void delete(Integer userinfoid)throws Exception;
	public abstract void update(Userinfo ui)throws Exception;
	public abstract Map manager(String pointPage,String operator)throws Exception;
	public abstract Userinfo find(Integer userinfoid)throws Exception;
	
}

public class UserinfoServiceImpl extends AbsPageService implements PageService,UserinfoService{
	/**
	 * 用户的删除方法
	 * @param Integer userinfoid
	 * */
	public void delete(Integer userinfoid) throws Exception {
		((UserinfoDAO)super.getDao()).delete(((UserinfoDAO)super.getDao()).findById(userinfoid));
	}
	
	/**
	 * 用户的查找方法
	 * @return Userinfo
	 * @param Integer userinfoid
	 * */
	public Userinfo find(Integer userinfoid) throws Exception {
		return ((UserinfoDAO)super.getDao()).findById(userinfoid);
	}
	
	/**
	 * 用户的管理方法
	 * @param String pointPage 当前页
	 * @param String operator 操作
	 * */
	public Map manager(String pointPage,String operator) throws Exception {
		this.setAph(new PageHold());
		this.getAph().setPs(this);
		return this.getAph().getUpsPage(pointPage, operator);
	}

	/**
	 * 用户的注册方法
	 * @param Userinfo userinfo
	 * */
	public void regist(Userinfo ui) throws Exception {
		((UserinfoDAO)super.getDao()).save(ui);		
	}

	/**
	 * 用户的更新方法
	 * @param Userinfo userinfo
	 * */
	public void update(Userinfo ui) throws Exception {
		((UserinfoDAO)super.getDao()).merge(ui);		
	}
	
	public AbsPageHold getAph() {
		return aph;
	}

	public void setAph(AbsPageHold aph) {
		this.aph = aph;
	}
	
	private AbsPageHold aph;

}

</pre><br /><br />工具类<br /><pre name="code" class="java">
public abstract class AbsPageHold {
	/**
	 * 获取页面的逻辑
	 * @return Map map
	 * @param String pointPage 当前页
	 * @param String operator 操作符 
	 * */
	public Map getUpsPage(String pointPage,String operator)throws Exception{
		Map map=null;
		try{
			if(operator==null){
				map=this.getFirstPage();
			}
			else if(operator.equals("first")){
				map=this.getFirstPage();
			}
			else if(operator.equals("previous")){
				map=this.getPreviousPage(pointPage);
			}
			else if(operator.equals("next")){
				map=this.getNextPage(pointPage);
			}
			else if(operator.equals("jump")){
				map=this.getJumpPage(pointPage);
			}
			else if(operator.equals("last")){
				map=this.getLastPage();
			}
			else{
				map=this.getFirstPage();
			}
		}
		catch(Exception e){
			System.out.println(e);
		}
		return map;
	}
	
	/**
	 * 分页所需要的帮助类
	 * */
	public Map getMap()throws Exception{
		Map map=new HashMap();
		map.put("totalCount",new Integer(this.getPs().getTotal()));
		map.put("totalPage", new Integer(this.getPs().getPageCount()));
		return map;
	}
	
	//模板方法
	public abstract Map getFirstPage()throws Exception;
	public abstract Map getLastPage()throws Exception;
	public abstract Map getNextPage(String pointPage)throws Exception;
	public abstract Map getPreviousPage(String pointPage)throws Exception;
	public abstract Map getJumpPage(String pointPage)throws Exception;
	
	//注入 
	public PageService getPs() {
		return ps;
	}
	public void setPs(PageService ps) {
		this.ps = ps;
	}
	private PageService ps;
}

public class PageHold extends AbsPageHold{
	
	public Map getFirstPage() throws Exception {
		Map map=super.getMap();
		map.put("pointPage", "1");
		map.put("list", this.getPs().getFirstPage());
		return map;
	}

	public Map getJumpPage(String pointPage) throws Exception {
		Map map=super.getMap();
		int i=Integer.parseInt(pointPage);
		List list=this.getPs().getPointPage(i);
		if(list!=null){
			map.put("pointPage", ""+(i));
			map.put("list", list);
		}
		else{
			map.put("pointPage", "1");
			map.put("list", this.getPs().getFirstPage());
		}
	
		return map;
	}

	public Map getLastPage() throws Exception {
		Map map=super.getMap();
		map.put("pointPage",((Integer)map.get("totalPage")).toString());
		map.put("list",this.getPs().getLastPage());
		return map;
	}


	public Map getNextPage(String pointPage) throws Exception {
		Map map=super.getMap();
		int i=Integer.parseInt(pointPage);
		List list=this.getPs().getNextPage(i);
		if(list!=null){
			map.put("pointPage", ""+(i+1));
			map.put("list", list);
		}
		else{
			map.put("pointPage", ""+this.getPs().getPageCount());
			map.put("list", this.getPs().getLastPage());
		}
	
		return map;
	}

	public Map getPreviousPage(String pointPage) throws Exception {
		Map map=super.getMap();
		int i=Integer.parseInt(pointPage);
		List list=this.getPs().getPreviousPage(i);
		if(list!=null){
			map.put("pointPage", ""+(i-1));
			map.put("list", list);
		}
		else{
			map.put("pointPage", "1");
			map.put("list",this.getPs().getFirstPage());	
		}
		return map;
	}

}
。
</pre><br /><br />现在问题是。我没有办法写一个通用的DAO接口实现CURD。<br />用伪泛型DAO无法解决注入问题。还有伪泛型DAO怎么处理SQL语句?放在Service层么？<br />似乎不怎么合适。<br />还有就是分页的时候PAGEHOLD(分页)和Userinfo相互交叉。<br />DTO传输应该放在什么地方？<br />等诸如此类的问题。请指点一下。
          <br/>
          <span style="color:red;">
            <a href="http://tales.javaeye.com/topic/229084#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 18 Aug 2008 09:35:46 +0800</pubDate>
        <link>http://www.javaeye.com/topic/229084</link>
        <guid>http://www.javaeye.com/topic/229084</guid>
      </item>
      <item>
        <title>getThis().getEvilAdvocate().setDead(getTrue())</title>
        <author>JavaEye网站</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://ajoo.javaeye.com">ajoo</a>&nbsp;
          链接：<a href="http://www.javaeye.com/topic/227866" style="color:red;">http://www.javaeye.com/topic/227866</a>&nbsp;
          发表时间: 2008年08月14日
          <br/>
          声明：本文系JavaEye网站发布的原创文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          code review过程中，看到这样的代码：<br /><pre name="code" class="java">
Pair&lt;String, String> getFooAndBar() {
  ...
}
</pre><br /><br />恶魔说，弄个Pair来表达FooAndBar不太容易理解，要不干脆弄个类把foo和bar封装起来，返回出来吧。<br /><br />天使：“同意”。<br /><br />下一版代码：<br /><pre name="code" class="java">
class FooAndBar {
  private final String foo;
  private final String bar;

  FooAndBar(String foo, String bar) {...}

  public String getFoo() {
    return foo;
  }

  public String getBar() {
    return bar;
  }
}
</pre><br /><br />嗯。恶魔不爽了。这个FooAndBar纯粹就是为了从函数里面返回几个有逻辑关系的值的组合。它不是public，也没有工具要用java bean api来读它，有必要一本正经地搞getFoo(), getBar()吗？直接就两个foo,bar field，简单点不好？<br /><br />天使：”反正就是IDE点几下，又不费事。“<br /><br />恶魔：”可是，它占行数啊。我看着没用的代码眼晕啊“<br /><br />天使：”getter可以控制只读“<br /><br />恶魔：”不是有final呢嘛？“<br /><br />天使：”用方法可以implement interface“<br /><br />恶魔：”可是这里没有interface啊。就是一个纯值对象“<br /><br />天使：”可以在getter()里面封装其它的逻辑，直接操作field没有这个灵活性“<br /><br />恶魔：”搜索整个代码库，几乎95%的情况下，getter/setter都是简单的get/set。有必要为这个旷世罕见的灵活性增加复杂度么？“<br /><br />天使：”getter是标准。sun推荐的。大家都这么干的“<br /><br />恶魔：（音乐起，微笑）”紧张的生活会造成心跳加快，内分泌失调，皮肤老化，头发枯黄。所以当可以get日和set日的时候，让我们放开身心，勇敢地被日以及日吧！“
          <br/>
          <span style="color:red;">
            <a href="http://tales.javaeye.com/topic/227866#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Thu, 14 Aug 2008 04:15:40 +0800</pubDate>
        <link>http://www.javaeye.com/topic/227866</link>
        <guid>http://www.javaeye.com/topic/227866</guid>
      </item>
      <item>
        <title>SPRING如何实现多数据源自动切换</title>
        <author>JavaEye网站</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://zh-zhai.javaeye.com">zh_zhai</a>&nbsp;
          链接：<a href="http://www.javaeye.com/topic/230002" style="color:red;">http://www.javaeye.com/topic/230002</a>&nbsp;
          发表时间: 2008年08月18日
          <br/>
          声明：本文系JavaEye网站发布的原创文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          由于项目中，数据库是负载均衡方式，有两个数据库实例。想用SPRING实现以下功能：若某台数据库宕掉，SPRING会自动切换至另外一个数据源。类似于WEBLOGIC的多数据源，LoadBalance方式。没有用hibernate做数据持久化，仅仅需要自动切换数据源。请问该如何实现。
          <br/>
          <span style="color:red;">
            <a href="http://tales.javaeye.com/topic/230002#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 18 Aug 2008 23:58:08 +0800</pubDate>
        <link>http://www.javaeye.com/topic/230002</link>
        <guid>http://www.javaeye.com/topic/230002</guid>
      </item>
      <item>
        <title>动态网站的缓存及个性化数据的显示处理</title>
        <author>JavaEye网站</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://leero.javaeye.com">leero</a>&nbsp;
          链接：<a href="http://www.javaeye.com/topic/228873" style="color:red;">http://www.javaeye.com/topic/228873</a>&nbsp;
          发表时间: 2008年08月17日
          <br/>
          声明：本文系JavaEye网站发布的原创文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p><span style="color: #ff0000;"><span style="background-color: #ffffff;">如题，不知道有的大型网站如何做的缓存，在页面上是如何显示个性化数据的[比如:登陆的动态信息]。</span></span><br /><br /><span style="color: #808000;">比如：淘宝，在它没一个商品页面都会有显示个性化数据[登陆信息:用户名，消息数量等的]，但是据我说知那页面肯定做了缓存的，要不然承受不了那么大的访问量。这就来问题了，居然做了缓存，为什么还能显示登陆信息？<br />1.假如是使用的cookie保存的个性化数据的，再从cookie里获取的信息显示到页面上，如果这个假如成立的话，那么从cookie里获取信息的话就只有两种方式：客户端和服务器端两种方式获取cookie信息，我看了下它的页面，没有找到任何使用客户端脚本获取cookie信息的代码。如果是从服务器端获取cookie信息的话那商品页面又如何能缓存呢？<br />2.假如是使用的session保存的个性化数据的，同上在服务器端读取cookie一样，页面又如何做到的缓存的？<br />3.难道是它只是针对未登陆用户做了缓存？不太可能，淘宝每天成交量都不低，故不太可能只针对登陆用户做缓冲。<br />4.难道是它使用了类似于oscache之类的缓存，页面中部分缓存，部分不缓存？</span><br /><br /><span style="font-size: medium;"><br /></span><strong><span style="color: #ff0000; font-size: medium;"><span style="background-color: #ffff99;">je也是同样的，如何即做到缓存又做到个性化数据的处理？</span></span></strong></p>
          <br/>
          <span style="color:red;">
            <a href="http://tales.javaeye.com/topic/228873#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sun, 17 Aug 2008 11:05:16 +0800</pubDate>
        <link>http://www.javaeye.com/topic/228873</link>
        <guid>http://www.javaeye.com/topic/228873</guid>
      </item>
      <item>
        <title>Facility Container 1.1 修改后的源代码及介绍</title>
        <author>JavaEye网站</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://xiaochen-su.javaeye.com">xiaochen_su</a>&nbsp;
          链接：<a href="http://www.javaeye.com/topic/229266" style="color:red;">http://www.javaeye.com/topic/229266</a>&nbsp;
          发表时间: 2008年08月18日
          <br/>
          声明：本文系JavaEye网站发布的原创文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          Facility Container 提供IOC的简易容器实现.<br />	---通过反射机制实现的IOC容器,简单而小巧.<br /><br />A.能够做的事情<br /><br />	1.根据上下文也就是配置文件创建组件.<br />	2.参数包括大部分的基本类型的创建,引用类型,集合参数类型(List Set Map Array).<br />	3.参数还可以引用其上下文中的组件.<br />	4.依赖注入的方式 通过构造函数,setter方法进行注入,还提供通过客户的配置调用任意方法的功能.<br /><br />B.不能够做的事情,并且下一步需要作的事情.<br /><br />	1.引用其他上下文中的组件.<br />	2.提供更好的上下文装饰策略接口 － 对创造好的容器的装饰 如日志打印装饰.<br /><br />C.配置文件的介绍<br />	让我们先看看xml配置文件把.<br /><br />	&lt;appname:components xmlns:appname = "http://xiaochen-su.javaeye.com/fc"><br />		&lt;component id = "" class = "" single = ""><br />			&lt;constructor><br />				...多个任意类型的参数<br />			&lt;/contructor><br />		<br />			&lt;setter name = ""><br />				...单个任意类型的参数<br />			&lt;/setter><br />				<br />			&lt;method name = ""><br />				...多个任意类型的参数<br />			&lt;/method><br />		&lt;/component><br />	&lt;/appname:components><br /><br />	以上是配置文件是一个组件元素的完整表示方式.<br /><br />		1.属性<br />			id是在容器的名称<br />			class就是组件的类型.<br />			single容器是否以单体保存(每次返回该类型的实力是否重新创建,默认值为true表示只有在头一次引用才创建组件的实体).<br />		2.子元素<br />			constructor	通过构造函数去创建一个组件.	<br />			setter	通过该setter方法进行注射. 需要提供属性名称.<br />			method	调用该方法.需要提供完整的方法名称.<br />			该方法必须都是容器可以访问到的保护级别.<br />		3.参数个数<br />			1..构造方法依赖注入	&lt;controller>&lt;property>...&lt;/property>&lt;/controller>	参数的长度可以有多个<br />			2.setter依赖注入 &lt;setter name = "id">&lt;property>...&lt;/property>&lt;/setter>	参数的长度仅能有一个<br />			3.method进行方法调用 &lt;method name = "setId">&lt;property>...&lt;/property>&lt;/method>	参数的长度可以有多个<br /><br />	参数类型<br />			&lt;property>&lt;short>&lt;/short>&lt;/property><br /><br />			&lt;property>&lt;int>&lt;/int>&lt;/property><br /><br />			&lt;property>&lt;long>&lt;/long>&lt;/property><br /><br />			&lt;property>&lt;float>&lt;/float>&lt;/property><br /><br />			&lt;property>&lt;double>&lt;/double>&lt;/property><br /><br />			&lt;property>&lt;boolean>&lt;/boolean>&lt;/property><br />				<br />			&lt;property>&lt;string>&lt;/string>&lt;/property><br /><br />			&lt;property>&lt;ref>&lt;/ref>&lt;/property><br /><br />			&lt;property><br />				&lt;list><br />					&lt;item>&lt;string>&lt;/string>&lt;/item><br />					&lt;item>&lt;ref>&lt;/ref>&lt;/item><br />				&lt;/list><br />			&lt;/property><br /><br />			&lt;property><br />				&lt;set><br />					&lt;item>&lt;string>&lt;/string>&lt;/item><br />					&lt;item>&lt;ref>&lt;/ref>&lt;/item><br />				&lt;/set><br />			&lt;/property><br /><br />			&lt;property><br />				&lt;array type = "java.lang.Object"><br />					&lt;item>&lt;string>&lt;/string>&lt;/item><br />					&lt;item>&lt;ref>&lt;/ref>&lt;/item><br />				&lt;/array><br />			&lt;/property><br /><br />			&lt;property><br />				&lt;map><br />					&lt;key name = "">&lt;string>&lt;/string>&lt;/key><br />					&lt;key name = "">&lt;ref>&lt;/ref>&lt;/key><br />				&lt;/map><br />			&lt;/property><br />		<br />	具体约束参见E.<br /><br />D.使用方法<br /><br />例子1.<br />&lt;um:components xmlns:um = "http://xiaochen-su.javaeye.com/fc"><br />	&lt;!-- 测试构造函数列表为null但通过ConstructorComponentScarfskin构造组件 --><br />	&lt;component id = "um_0" class = "demo.component.UserModel"><br />		&lt;setter name = "id"><br />			&lt;property><br />				&lt;int>1100&lt;/int><br />			&lt;/property><br />		&lt;/setter><br />		<br />		&lt;setter name = "userName"><br />			&lt;property>&lt;string>用户名 - 你好世界&lt;/string>&lt;/property><br />		&lt;/setter><br />		<br />		&lt;setter name = "password"><br />			&lt;property>&lt;string>密码 - 世界你好&lt;/string>&lt;/property><br />		&lt;/setter><br />		<br />		&lt;setter name = "email"><br />			&lt;property>&lt;string>电子邮件 - 世界你好@HelloWorld.com&lt;/string>&lt;/property><br />		&lt;/setter><br />		<br />		&lt;method name = "print"><br />			&lt;property><br />				&lt;ref>out&lt;/ref><br />			&lt;/property><br />			&lt;property><br />				&lt;string>上下文打印信息&lt;/string><br />			&lt;/property><br />		&lt;/method><br />		<br />		&lt;method name = "print"/><br />	<br />	&lt;/component><br />	<br />	&lt;component id = "out" class = "java.io.PrintStream"><br />		&lt;constructor><br />			&lt;property><br />				&lt;string>/home/suchen/files/user model.txt&lt;/string><br />			&lt;/property><br />		&lt;/constructor><br />	&lt;/component><br />&lt;/um:components><br /><br />		package demo.component;<br /><br /><br /><br />import java.io.IOException;<br /><br />import java.io.OutputStream;<br /><br />import java.io.PrintStream;<br /><br /><br /><br />/**<br /><br /> * 用户模型.<br /><br /> * <br /><br /> * @author suchen<br /><br /> * @time 2008-7-30 上午10:41:30<br /><br /> * @email xiaochen_su@126.com<br /><br /> */<br /><br />public class UserModel {<br /><br />	private int id;<br /><br />	private String password;<br /><br />	private String userName;<br /><br />	private String email;<br /><br />	<br /><br />	public UserModel() {<br /><br />		<br /><br />	}<br /><br />	<br /><br />	public UserModel(int id, String userName, String password, String email) {<br /><br />		this.id = id;<br /><br />		this.userName = userName;<br /><br />		this.password = password;<br /><br />		this.email = email;<br /><br />	}<br /><br />	<br /><br />	public String getEmail() {<br /><br />		return email;<br /><br />	}<br /><br />	<br /><br />	public void setEmail(String email) {<br /><br />		this.email = email;<br /><br />	}<br /><br />	<br /><br />	public int getId() {<br /><br />		return id;<br /><br />	}<br /><br />	<br /><br />	public void setId(int id) {<br /><br />		this.id = id;<br /><br />	}<br /><br />	<br /><br />	public String getPassword() {<br /><br />		return password;<br /><br />	}<br /><br />	<br /><br />	public void setPassword(String password) {<br /><br />		this.password = password;<br /><br />	}<br /><br />	<br /><br />	public String getUserName() {<br /><br />		return userName;<br /><br />	}<br /><br />	<br /><br />	public void setUserName(String userName) {<br /><br />		this.userName = userName;<br /><br />	}<br /><br />	<br /><br />	public void print() {<br /><br />		<br /><br />		System.out.println(toString());<br /><br />	}<br /><br />	<br /><br />	public void print(PrintStream out, String title) {<br /><br />		out.print(title + " # ");<br /><br />		out.println(toString());<br /><br />	}<br /><br />	<br /><br />	public void print(OutputStream out, String title) {<br /><br />		try {<br /><br />			out.write(("print(OutputStream, String) # " + title + " # " + toString()).getBytes());<br /><br />			out.close();<br /><br />		} catch (IOException e) {<br /><br />			// TODO Auto-generated catch block<br /><br />			e.printStackTrace();<br /><br />		}<br /><br />	<br /><br />	}<br /><br />	<br /><br />	public String toString() {<br /><br />		return "[id] " + id + " [userName] " + userName + " [password] " + password + " [email] " + email;<br /><br />	}<br /><br />	<br /><br />}<br /><br /><br /><br />		try {<br />			FacilityContainerContext containerContext = new ClassPathFacilityContainerContext("demo/testing/file/user-model.xml");	//1<br />			containerContext.getComponentByKey("um_0");	//2<br />		} catch (IOException e) {<br />			// TODO Auto-generated catch block<br />			e.printStackTrace();<br />		}<br /><br />		执行以上这段代码将会在屏幕上打印  [id] 1100 [userName] 用户名 - 你好世界 [password] 密码 - 世界你好 [email] 电子邮件 - 世界你好@HelloWorld.com<br />		<br />		第一行创建了一个根据类路径查找配置的上下文<br />		第二行是从上下文返回该组件,该组件设置为单体第一次调用会构造这个组建并创造依赖把并把实体和注入所需要的依赖保存住.<br />		屏幕上打印字符串的方法是由&lt;method name = "print"/>表示的,也就是public void print()方法.<br />		在/home/suchen/files/user model.txt下打印的由<br />		&lt;method name = "print"><br />			&lt;property><br />				&lt;ref>out&lt;/ref><br />			&lt;/property><br />			&lt;property><br />				&lt;string>上下文打印信息&lt;/string><br />			&lt;/property><br />		&lt;/method><br />		标记表示,也就是public void print(PrintStream outStream, String title)方法.<br /><br />	例子2<br />		&lt;component id = "smcms" class = "demo.component.SetterMethodCollectionModel"><br />		&lt;setter name = "array"><br />			&lt;property><br />				&lt;array type = "java.lang.Object"><br />					&lt;item>&lt;string>setter - array - str - value&lt;/string>&lt;/item><br />					&lt;item>&lt;string>setter - array - str1 - value&lt;/string>&lt;/item><br />					&lt;item>&lt;string>setter - array - str2 - value&lt;/string>&lt;/item><br />					&lt;item>&lt;string>setter - array - str3 - value&lt;/string>&lt;/item><br />					&lt;item>&lt;string>setter - array - str4 - value&lt;/string>&lt;/item><br />					&lt;item>&lt;ref>createdate&lt;/ref>&lt;/item><br />				&lt;/array><br />			&lt;/property><br />		&lt;/setter><br />		&lt;setter name = "array1"><br />			&lt;property><br />				&lt;array type = "java.lang.Object"><br />					&lt;item>&lt;string>setter - array1 - str - value&lt;/string>&lt;/item><br />					&lt;item>&lt;string>setter - array1 - str1 - value&lt;/string>&lt;/item><br />					&lt;item>&lt;string>setter - array1 - str2 - value&lt;/string>&lt;/item><br />					&lt;item>&lt;string>setter - array1 - str3 - value&lt;/string>&lt;/item><br />					&lt;item>&lt;string>setter - array1 - str4 - value&lt;/string>&lt;/item><br />					&lt;item>&lt;ref>createdate&lt;/ref>&lt;/item><br />				&lt;/array><br />			&lt;/property><br />		&lt;/setter><br />		&lt;setter name = "set"><br />			&lt;property><br />				&lt;set><br />					&lt;item>&lt;string>setter - set - str - value&lt;/string>&lt;/item><br />					&lt;item>&lt;string>setter - set - str1 - value&lt;/string>&lt;/item><br />					&lt;item>&lt;string>setter - set - str2 - value&lt;/string>&lt;/item><br />					&lt;item>&lt;string>setter - set - str3 - value&lt;/string>&lt;/item><br />					&lt;item>&lt;string>setter - set - str4 - value&lt;/string>&lt;/item><br />					&lt;item>&lt;ref>createdate&lt;/ref>&lt;/item><br />				&lt;/set><br />			&lt;/property><br />		&lt;/setter><br />		&lt;setter name = "set1"><br />			&lt;property><br />				&lt;set><br />					&lt;item>&lt;string>setter - set1 - str - value&lt;/string>&lt;/item><br />					&lt;item>&lt;string>setter - set1 - str1 - value&lt;/string>&lt;/item><br />					&lt;item>&lt;string>setter - set1 - str2 - value&lt;/string>&lt;/item><br />					&lt;item>&lt;string>setter - set1 - str3 - value&lt;/string>&lt;/item><br />					&lt;item>&lt;string>setter - set1 - str4 - value&lt;/string>&lt;/item><br />					&lt;item>&lt;ref>createdate&lt;/ref>&lt;/item><br />				&lt;/set><br />			&lt;/property><br />		&lt;/setter><br />		&lt;setter name = "map"><br />			&lt;property><br />				&lt;map><br />					&lt;key name = "str">&lt;string>setter - map - str - value&lt;/string>&lt;/key><br />					&lt;key name = "str1">&lt;string>setter - map - str1 - value&lt;/string>&lt;/key><br />					&lt;key name = "str2">&lt;string>setter - map - str2 - value&lt;/string>&lt;/key><br />					&lt;key name = "str3">&lt;string>setter - map - str3 - value&lt;/string>&lt;/key><br />					&lt;key name = "str4">&lt;string>setter - map - str4 - value&lt;/string>&lt;/key><br />					&lt;key name = "createDate">&lt;ref>createdate&lt;/ref>&lt;/key><br />				&lt;/map><br />			&lt;/property><br />		&lt;/setter><br />		&lt;setter name = "map1"><br />			&lt;property><br />				&lt;map><br />					&lt;key name = "str">&lt;string>setter - map1 - str - value&lt;/string>&lt;/key><br />					&lt;key name = "str1">&lt;string>setter - map1 - str1 - value&lt;/string>&lt;/key><br />					&lt;key name = "str2">&lt;string>setter - map1 - str2 - value&lt;/string>&lt;/key><br />					&lt;key name = "str3">&lt;string>setter - map1 - str3 - value&lt;/string>&lt;/key><br />					&lt;key name = "str4">&lt;string>setter - map1 - str4 - value&lt;/string>&lt;/key><br />					&lt;key name = "createDate">&lt;ref>createdate&lt;/ref>&lt;/key><br />				&lt;/map><br />			&lt;/property><br />		&lt;/setter><br />		&lt;setter name = "list"><br />			&lt;property><br />				&lt;list><br />					&lt;item>&lt;string>setter - list - str - value&lt;/string>&lt;/item><br />					&lt;item>&lt;string>setter - list - str1 - value&lt;/string>&lt;/item><br />					&lt;item>&lt;string>setter - list - str2 - value&lt;/string>&lt;/item><br />					&lt;item>&lt;string>setter - list - str3 - value&lt;/string>&lt;/item><br />					&lt;item>&lt;string>setter - list - str4 - value&lt;/string>&lt;/item><br />					&lt;item>&lt;ref>createdate&lt;/ref>&lt;/item><br />				&lt;/list><br />			&lt;/property><br />		&lt;/setter><br />		&lt;setter name = "list1"><br />			&lt;property><br />				&lt;list><br />					&lt;item>&lt;string>setter - list1 - str - value&lt;/string>&lt;/item><br />					&lt;item>&lt;string>setter - list1 - str1 - value&lt;/string>&lt;/item><br />					&lt;item>&lt;string>setter - list1 - str2 - value&lt;/string>&lt;/item><br />					&lt;item>&lt;string>setter - list1 - str3 - value&lt;/string>&lt;/item><br />					&lt;item>&lt;string>setter - list1 - str4 - value&lt;/string>&lt;/item><br />					&lt;item>&lt;ref>createdate&lt;/ref>&lt;/item><br />				&lt;/list><br />			&lt;/property><br />		&lt;/setter><br />	&lt;/component><br /><br />	public class SetterMethodCollectionModel {<br />	private List list = null;<br /><br />	private Set set = null;<br /><br />	private Map map = null;<br /><br />	private List list1 = null;<br /><br />	private Set set1 = null;<br /><br />	private Map map1 = null;<br /><br />	private Object[] array = null;<br /><br />	private Object[] array1 = null;<br />	<br />	//setter getter方法	<br /><br />	public String toString() {<br />		StringBuffer buffer = new StringBuffer();<br />		<br />		buffer.append("list\n").append(StringUtils.toString(list));<br />		buffer.append("list1\n").append(StringUtils.toString(list1));<br />		buffer.append("array\n").append(StringUtils.toString(array));<br />		buffer.append("array1\n").append(StringUtils.toString(array1));<br />		buffer.append("set\n").append(StringUtils.toString(set));<br />		buffer.append("set1\n").append(StringUtils.toString(set1));<br />		buffer.append("map\n").append(StringUtils.toString(map));<br />		buffer.append("map1\n").append(StringUtils.toString(map1));<br />		<br />		return buffer.toString();<br />	}<br />	}<br /><br />	public static void testingDoubleCollectionSetter() {<br />		try {<br />			FacilityContainerContext containerContext = <br />						new ClassPathFacilityContainerContext("demo/testing/file/collection-testing.xml");<br />			<br />			SetterMethodCollectionModel smcms = (SetterMethodCollectionModel)containerContext.getComponentByKey("smcms");<br />			System.out.println(smcms);<br />		}  catch (IOException e) {<br />			// TODO Auto-generated catch block<br />			e.printStackTrace();<br />		}<br />	}<br /><br />	这个是打印集合类型.<br />更多的测试实例参见demo包下的类.<br /><br />E.支持类型<br /><br />	参数类型<br />		1.集合参数的支持	<br />			&lt;list><br />				&lt;item>&lt;string>&lt;/string>&lt;/item><br />				&lt;item>&lt;ref>&lt;/ref>&lt;/item><br />			&lt;/list><br />			&lt;set><br />				&lt;item>&lt;string>&lt;/string>&lt;/item><br />				&lt;item>&lt;ref>&lt;/ref>&lt;/item><br />			&lt;/set><br />			&lt;array type = "java.lang.Object"><br />				&lt;item>&lt;string>&lt;/string>&lt;/item><br />				&lt;item>&lt;ref>&lt;/ref>&lt;/item><br />			&lt;/array><br />			&lt;map><br />				&lt;key name = "">&lt;string>&lt;/string>&lt;/key><br />				&lt;key name = "">&lt;ref>&lt;/ref>&lt;/key><br />			&lt;/map><br />		2.基本类型的支持	<br />			short, int, long, float, double, boolean<br /><br />F.简单的小应用<br />	很简单的小应用连接数据库有 insert select update 三种操作的小应用.<br />	用户在一个网页上 插入信息 更新信息 查看信息的操作.
          <br/>
          <span style="color:red;">
            <a href="http://tales.javaeye.com/topic/229266#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 18 Aug 2008 16:24:29 +0800</pubDate>
        <link>http://www.javaeye.com/topic/229266</link>
        <guid>http://www.javaeye.com/topic/229266</guid>
      </item>
      <item>
        <title>com.sun.awt.AWTUtilities /  透明和不规则 Swing 窗口</title>
        <author>JavaEye网站</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://niceo.javaeye.com">niceo</a>&nbsp;
          链接：<a href="http://www.javaeye.com/topic/229179" style="color:red;">http://www.javaeye.com/topic/229179</a>&nbsp;
          发表时间: 2008年08月18日
          <br/>
          声明：本文系JavaEye网站发布的原创文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <span style="color: blue">  在进行Swing外观调整的时候发现com.sun.awt.AWTUtilities <br />　 这个有ＳＵＮ公司直接提供的的东东。<br />　于是就像试验一下。<br />结果发现这东西只能在　jdk-6u10　的版本中才能体现出来的；</span><br />／／－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－<br /><span style="color: red">在官方有这样一句话：<br /><br />Java SE 6 Update N， 通常称作 Consumer JRE， 是 Sun 公司的努力成果，为重新配置 Java　将其作为开发富桌面应用程序的可行方法。在 Consumer JRE 中的新功能和主要改进列表相当广泛，并将特别闪耀的宝石隐藏在最新一周构建代码之一的发行说明中。<br /><br />　　　在进一步研究之前，有一个非常重要的注意事项。由于 Consumer JRE 被官方认为是对稳定 JDK 发行的一个次要更新，因此在“公共”包中不能添加任何新的 API（ 类、方法等等 ），例如 java.awt 或 javax.swing。在本文中讨论的所有 API 在新 com.sun.awt.AWTUtilities 类中出现，该类不是官方支持的部分 API。它在 Java SE 7 中的位置最有可能发生改变，签名方法可能在现在和最终的 Consumer JRE 发行之间发生轻微变化。</span><br />／／－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－<br /><br />所以当你的ＪＤｋ版本不匹配的时候需要你将JDK插件更新。<br />可以在<br /><span style="color: brown">https://jdk6.dev.java.net/6u10ea.html<br /><br />Java SE 6 Runtime (JRE) Update 10 build 28 Windows Online Installer<br />Java SE 6 Runtime (JRE) Update 10 build 28 Windows Offline Installer <br />jdk-6u10-rc-bin-b28-windows-i586-debug-21_jul_2008.jar</span><br /><br />下载安装以后：找到这样的一段在官方的代码运行结果令我很是满意。<br />代码如下：<br /><br /><pre name="code" class="java">
import java.awt.*;
import javax.swing.*;

public class TranslucentWindow extends JFrame {
	public TranslucentWindow() {
		super("Test translucent window");
		this.setLayout(new FlowLayout());
		this.add(new JButton("test"));
		this.add(new JCheckBox("test"));
		this.add(new JRadioButton("test"));
		this.add(new JProgressBar(0, 100));

		this.setSize(new Dimension(400, 300));
		this.setLocationRelativeTo(null);
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	}

	public static void main(String[] args) {
		JFrame.setDefaultLookAndFeelDecorated(true);
		SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				Window w = new TranslucentWindow();
				w.setVisible(true);

        //要使窗口透明，您可以使用 AWTUtilities.setWindowOpacity(Window, float) 方法
				com.sun.awt.AWTUtilities.setWindowOpacity(w, 0.5f);
			}
		});
	}

}

</pre><br />／／－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－<br />详细请参考：<br /><span style="color: red"><a href="https://jdk6.dev.java.net/6u10ea.html" target="_blank">https://jdk6.dev.java.net/6u10ea.html</a><br /><a href="http://developers.sun.com.cn/Java/translucent-and-shaped-swing-windows.html" target="_blank">http://developers.sun.com.cn/Java/translucent-and-shaped-swing-windows.html</a><br /></span><br />//----------------------------------------------<br />这是几个测试的例子：<br />官方提供的：
          <br/>
          <span style="color:red;">
            <a href="http://tales.javaeye.com/topic/229179#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 18 Aug 2008 13:52:52 +0800</pubDate>
        <link>http://www.javaeye.com/topic/229179</link>
        <guid>http://www.javaeye.com/topic/229179</guid>
      </item>
      <item>
        <title>AOP原理及在架构设计中的应用(三)</title>
        <author>JavaEye网站</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://raymond2006k.javaeye.com">raymond2006k</a>&nbsp;
          链接：<a href="http://www.javaeye.com/topic/229036" style="color:red;">http://www.javaeye.com/topic/229036</a>&nbsp;
          发表时间: 2008年08月17日
          <br/>
          声明：本文系JavaEye网站发布的原创文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <div class="Section1" style="layout-grid: 15.6pt none;">
<p class="a1" style="margin-left: 21pt; text-indent: 21pt;"><strong style="mso-bidi-font-weight: normal;"><span style="font-size: 14pt; color: windowtext; font-family: 黑体;">AOP</span></strong><strong style="mso-bidi-font-weight: normal;"><span style="font-size: 14pt; color: windowtext; font-family: 黑体;">原理及在架构设计中的应用(三)</span></strong></p>
<p class="a1" align="right" style="text-align: right;"><span style="font-size: 12pt; color: windowtext;">&nbsp;</span></p>
<p class="a1" style="text-justify: inter-ideograph; text-align: justify;"><span style="font-size: 12pt; font-family: 宋体;">【</span><span style="font-size: 12pt; font-family: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman';">摘要</span><span style="font-size: 12pt; font-family: 宋体;">】 面向方面的编程<span lang="EN-US">(AOP)</span>技术已在<span lang="EN-US">Java</span>领域产生多年，它为传统的编程模式带来了一种新的思维和方式。<span lang="EN-US">AOP</span>本身为程序结构带来的灵活性，在<span class="SpellE"><span lang="EN-US">JavaEE</span></span>架构设计上也能发挥极大的作用。本文对<span lang="EN-US">AOP</span>原理，<span lang="EN-US">Spring AOP</span>基本编码方式进行了简明，清晰的介绍，还对公司项目实践中<span lang="EN-US">AOP</span>的基本应用模式进行了归纳，整理<span lang="EN-US">, </span>有更贴近实践的指导意义。 </span></p>
<p class="a1" style="text-justify: inter-ideograph; text-align: justify;"><span style="font-size: 12pt; color: windowtext;">&nbsp;</span></p>
<p class="a1" style="text-justify: inter-ideograph; text-align: justify;"><span style="font-size: 12pt; font-family: 宋体;">【</span><span style="font-size: 12pt; font-family: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman';">关键词</span><span style="font-size: 12pt; font-family: 宋体;">】<span lang="EN-US">AOP <span style="mso-spacerun: yes;">&nbsp;</span><span class="SpellE">JavaEE</span> </span>架构设计</span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size: 12pt;">&nbsp;</span></p>
<h1 style="margin: 0cm 0cm 6pt 21.25pt;">
<p class="MsoNormal">&nbsp;</p>
<span style="font-size: 14pt; font-family: 'Times New Roman'; mso-fareast-font-family: 'Times New Roman';"><span style="mso-list: Ignore;">2.2.<span style="font-family: 'Times New Roman';">&nbsp;&nbsp;&nbsp; </span></span></span><span style="font-size: 14pt; font-family: 'Times New Roman'; mso-fareast-font-family: 宋体;">AOP </span><span style="font-size: 14pt; font-family: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman';">应用举例</span></h1>
<h3 style="margin: 0cm 0cm 0pt 35.45pt; line-height: normal; tab-stops: 35.45pt;"><span lang="EN-US" style="font-size: 14pt; mso-fareast-font-family: 'Times New Roman';"><span style="mso-list: Ignore;">2.2.1.<span style="font-family: 'Times New Roman';"> </span></span></span><span style="font-size: 14pt; font-family: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman';">基本功能</span></h3>
<p class="MsoNormal" style="margin-left: 18pt; text-indent: -18pt; mso-list: l14 level1 lfo26; tab-stops: list 18.0pt;"><strong style="mso-bidi-font-weight: normal;"><span lang="EN-US" style="mso-fareast-font-family: 'Times New Roman';"><span style="mso-list: Ignore;">1.<span style="font-family: 'Times New Roman';">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span></strong><strong style="mso-bidi-font-weight: normal;"><span style="font-family: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman';">业务日志（工单）</span></strong></p>
<p class="MsoNormal"><span lang="EN-US"><span style="mso-tab-count: 1;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman';">凡是基于数据库的系统，本质上都是对<span class="GramE">库表记录</span>的增删改查。而从业务层面看，很多时候，用户需要对数据的操作留下痕迹，即业务日志，以便审计。</span></p>
<p class="MsoNormal"><span lang="EN-US"><span style="mso-tab-count: 1;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman';">在公司项目的</span><span lang="EN-US">J2EE</span><span style="font-family: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman';">架构中设计了业务日志拦截器，并切入对</span><span lang="EN-US">BO</span><span style="font-family: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman';">的操作，完成对业务操作的记录。用户可以通过专门的界面对业务日志进行查询和分析。</span></p>
<p class="MsoNormal"><span lang="EN-US"><span style="mso-tab-count: 1;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><strong style="mso-bidi-font-weight: normal;"><span style="font-family: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman';">工作原理</span></strong></p>
<p class="MsoNormal"><span lang="EN-US"><span style="mso-tab-count: 1;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman';">业务日志的基本数据格式为：</span></p>
<p class="MsoNormal"><span lang="EN-US"><span style="mso-tab-count: 1;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="background: #d9d9d9; mso-shading: white; mso-pattern: gray-15 auto;"><span style="mso-spacerun: yes;">&nbsp;</span></span></span><strong style="mso-bidi-font-weight: normal;"><span style="background: #d9d9d9; font-family: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'; mso-shading: white; mso-pattern: gray-15 auto;">操作时间</span><span lang="EN-US" style="background: #d9d9d9; mso-shading: white; mso-pattern: gray-15 auto;">,</span></strong><strong style="mso-bidi-font-weight: normal;"><span style="background: #d9d9d9; font-family: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'; mso-shading: white; mso-pattern: gray-15 auto;">来源</span><span lang="EN-US" style="background: #d9d9d9; mso-shading: white; mso-pattern: gray-15 auto;">IP,</span></strong><strong style="mso-bidi-font-weight: normal;"><span style="background: #d9d9d9; font-family: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'; mso-shading: white; mso-pattern: gray-15 auto;">操作工号</span><span lang="EN-US" style="background: #d9d9d9; mso-shading: white; mso-pattern: gray-15 auto;">,</span></strong><strong style="mso-bidi-font-weight: normal;"><span style="background: #d9d9d9; font-family: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'; mso-shading: white; mso-pattern: gray-15 auto;">操作状态</span><span lang="EN-US" style="background: #d9d9d9; mso-shading: white; mso-pattern: gray-15 auto;">,</span></strong><strong style="mso-bidi-font-weight: normal;"><span style="background: #d9d9d9; font-family: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'; mso-shading: white; mso-pattern: gray-15 auto;">操作动作</span><span lang="EN-US" style="background: #d9d9d9; mso-shading: white; mso-pattern: gray-15 auto;">,</span></strong><strong style="mso-bidi-font-weight: normal;"><span style="background: #d9d9d9; font-family: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'; mso-shading: white; mso-pattern: gray-15 auto;">操作类型</span><span lang="EN-US" style="background: #d9d9d9; mso-shading: white; mso-pattern: gray-15 auto;">,</span></strong><strong style="mso-bidi-font-weight: normal;"><span style="background: #d9d9d9; font-family: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'; mso-shading: white; mso-pattern: gray-15 auto;">失败原因</span><span lang="EN-US" style="background: #d9d9d9; mso-shading: white; mso-pattern: gray-15 auto;">,</span></strong><strong style="mso-bidi-font-weight: normal;"><span style="background: #d9d9d9; font-family: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'; mso-shading: white; mso-pattern: gray-15 auto;">数据</span><span style="background: #d9d9d9; mso-shading: white; mso-pattern: gray-15 auto;"> </span></strong></p>
<p class="MsoNormal"><span lang="EN-US"><span style="mso-tab-count: 1;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman';">日志按操作类型分：增加，删除，修改（查询暂不记录），</span> <span style="font-family: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman';">操作成功，失败时都要记录。记录业务日志的主要依据是被拦截的对象和方法信息，。在执行方法本体后，即业务方法成功执行后，记录成功日志；在方法本体抛出异常时，记录失败日志。主要代码见下：</span></p>
<p class="MsoNormal"><span lang="EN-US">
<table cellspacing="0" border="0" width="100%" cellpadding="0">
<tbody>
<tr>
<td>
<div>
<p class="MsoNormal"><span class="GramE"><strong><span style="font-size: 10pt; background: yellow; color: #7f0055; font-family: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体; mso-highlight: yellow;">public</span></strong></span><span style="font-size: 10pt; background: yellow; color: #000000; font-family: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体; mso-highlight: yellow;"> </span><strong><span style="font-size: 10pt; background: yellow; color: #7f0055; font-family: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体; mso-highlight: yellow;">class</span></strong><span style="font-size: 10pt; background: yellow; color: #000000; font-family: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体; mso-highlight: yellow;"> <span class="SpellE">BusinessLogAdvisor</span> </span><strong><span style="font-size: 10pt; background: yellow; color: #7f0055; font-family: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体; mso-highlight: yellow;">extends</span></strong><span style="font-size: 10pt; background: yellow; color: #000000; font-family: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体; mso-highlight: yellow;"> <span class="SpellE">AbstractAdvisor</span><span style="mso-spacerun: yes;">&nbsp; </span>{</span></p>
<p class="MsoNormal"><span style="font-size: 10pt; color: #000000; font-family: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体;">&nbsp;</span></p>
<p class="MsoNormal"><span class="GramE"><strong><span style="font-size: 10pt; background: yellow; color: #7f0055; font-family: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体; mso-highlight: yellow;">public</span></strong></span><span style="font-size: 10pt; background: yellow; color: #000000; font-family: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体; mso-highlight: yellow;"> Object invoke(<span class="SpellE">MethodInvocation</span> invocation) </span><strong><span style="font-size: 10pt; background: yellow; color: #7f0055; font-family: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体; mso-highlight: yellow;">throws</span></strong><span style="font-size: 10pt; background: yellow; color: #000000; font-family: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体; mso-highlight: yellow;"> <span class="SpellE">Throwable</span> {</span></p>
<p class="MsoNormal" align="left" style="text-align: left; mso-layout-grid-align: none;"><span style="font-size: 10pt; color: #000000; font-family: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体;"><span style="mso-tab-count: 1;">&nbsp;&nbsp;&nbsp; </span></span><span style="font-size: 10pt; color: #008000; font-family: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体;">//</span><span style="font-size: 10pt; color: #008000; font-family: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体;">准备参数</span></p>
<p class="MsoNormal" align="left" style="text-align: left; mso-layout-grid-align: none;"><span style="font-size: 10pt; color: #000000; font-family: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体;"><span style="mso-tab-count: 1;">&nbsp;&nbsp;&nbsp; </span>Object result = </span><strong><span style="font-size: 10pt; color: #7f0055; font-family: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体;">null</span></strong><span style="font-size: 10pt; color: #000000; font-family: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体;">;<span style="mso-tab-count: 2;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></p>
<p class="MsoNormal" align="left" style="text-align: left; mso-layout-grid-align: none;"><span style="font-size: 10pt; color: #000000; font-family: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体;"><span style="mso-tab-count: 1;">&nbsp;&nbsp;&nbsp; </span>Object <span class="SpellE"><span style="background: silver; mso-highlight: silver;">object</span></span> = <span class="SpellE">invocation.getThis</span>(); </span><span style="font-size: 10pt; color: #008000; font-family: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体;">//</span><span style="font-size: 10pt; color: #008000; font-family: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体;">被拦截的对象</span></p>
<p class="MsoNormal" align="left" style="text-align: left; mso-layout-grid-align: none;"><span style="font-size: 10pt; color: #000000; font-family: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体;"><span style="mso-tab-count: 1;">&nbsp;&nbsp;&nbsp; </span>Method <span class="SpellE">method</span> = <span class="SpellE">invocation.getMethod</span>(); </span><span style="font-size: 10pt; color: #008000; font-family: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体;">//</span><span style="font-size: 10pt; color: #008000; font-family: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体;">被拦截的方法</span></p>
<p class="MsoNormal" align="left" style="text-align: left; mso-layout-grid-align: none;"><span style="font-size: 10pt; color: #000000; font-family: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体;"><span style="mso-tab-count: 1;">&nbsp;&nbsp;&nbsp; </span>Object[] <span class="SpellE">args</span> = <span class="SpellE">invocation.getArguments</span>(); </span><span style="font-size: 10pt; color: #008000; font-family: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体;">// </span><span style="font-size: 10pt; color: #008000; font-family: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体;">参数<span lang="EN-US"><span style="mso-tab-count: 1;">&nbsp; </span></span></span></p>
<p class="MsoNormal" align="left" style="text-align: left; mso-layout-grid-align: none;"><span style="font-size: 10pt; color: #000000; font-family: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体;"><span style="mso-tab-count: 1;">&nbsp;&nbsp;&nbsp; </span></span><span style="font-size: 10pt; color: #008000; font-family: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体;">//before, </span><span style="font-size: 10pt; color: #008000; font-family: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体;">之前必要的检查</span></p>
<p class="MsoNormal" align="left" style="text-align: left; mso-layout-grid-align: none;"><span style="font-size: 10pt; color: #000000; font-family: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体;"><span style="mso-tab-count: 1;">&nbsp;&nbsp;&nbsp; </span></span><span style="font-size: 10pt; color: #000000; mso-ascii-font-family: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体;">&hellip;&hellip;</span></p>
<p class="MsoNormal" align="left" style="text-align: left; mso-layout-grid-align: none;"><span style="font-size: 10pt; color: #000000; font-family: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体;"><span style="mso-tab-count: 1;">&nbsp;&nbsp;&nbsp; </span></span><span class="GramE"><strong><span style="font-size: 10pt; background: yellow; color: #7f0055; font-family: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体; mso-highlight: yellow;">try</span></strong></span><span style="font-size: 10pt; background: yellow; color: #000000; font-family: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体; mso-highlight: yellow;"> {</span></p>
<p class="MsoNormal" align="left" style="text-align: left; mso-layout-grid-align: none;"><span style="font-size: 10pt; color: #000000; font-family: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体;"><span style="mso-tab-count: 2;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span class="GramE">result</span> = <span class="SpellE">invocation.proceed</span>();</span></p>
<p class="MsoNormal" align="left" style="text-align: left; mso-layout-grid-align: none;"><span style="font-size: 10pt; color: #000000; font-family: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体;"><span style="mso-tab-count: 2;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-size: 10pt; color: #008000; font-family: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体;">//</span><span style="font-size: 10pt; color: #008000; font-family: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体;">以下执行记录日志的操作</span></p>
<p class="MsoNormal" align="left" style="text-align: left; mso-layout-grid-align: none;"><span style="font-size: 10pt; color: #000000; font-family: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体;"><span style="mso-tab-count: 1;">&nbsp;&nbsp;&nbsp; </span><span style="mso-tab-count: 1;">&nbsp;&nbsp;&nbsp; </span><span class="SpellE"><span class="GramE">doLog</span></span><span class="GramE">(</span>object, method, <span class="SpellE">args</span>, target, <span class="SpellE">BusinessLog.<em><span style="color: #0000c0;">STATE_SUCCESS</span></em>,<strong><span style="color: #7f0055;">null</span></strong></span>);</span></p>
<p class="MsoNormal" align="left" style="text-align: left; mso-layout-grid-align: none;"><span style="font-size: 10pt; color: #000000; font-family: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体;"><span style="mso-tab-count: 1;">&nbsp;&nbsp;&nbsp; </span><span class="GramE">}<strong><span style="background: yellow; color: #7f0055; mso-highlight: yellow;">catch</span></strong></span><span style="background: yellow; mso-highlight: yellow;">(Exception e) {</span></span></p>
<p class="MsoNormal" align="left" style="text-align: left; mso-layout-grid-align: none;"><span style="font-size: 10pt; color: #000000; font-family: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体;"><span style="mso-tab-count: 2;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-size: 10pt; color: #008000; font-family: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体;">//</span><span style="font-size: 10pt; color: #008000; font-family: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体;">以下记录失败日志</span></p>
<p class="MsoNormal" align="left" style="text-align: left; mso-layout-grid-align: none;"><span style="font-size: 10pt; color: #000000; font-family: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体;"><span style="mso-tab-count: 2;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span class="SpellE"><span class="GramE"><span style="background: yellow; mso-highlight: yellow;">doLog</span></span></span><span class="GramE"><span style="background: yellow; mso-highlight: yellow;">(</span></span><span style="background: yellow; mso-highlight: yellow;">object, method, <span class="SpellE">args</span>, </span><span style="background: silver; mso-highlight: silver;">target</span><span style="background: yellow; mso-highlight: yellow;">, <span class="SpellE">BusinessLog.<em><span style="color: #0000c0;">STATE_FAIL</span></em>,failcause</span>);</span></span></p>
<p class="MsoNormal" align="left" style="text-align: left; mso-layout-grid-align: none;"><span style="font-size: 10pt; color: #000000; font-family: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体;"><span style="mso-tab-count: 1;">&nbsp;&nbsp;&nbsp; </span>}</span></p>
<p class="MsoNormal"><span style="font-size: 10pt; color: #000000; font-family: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体;">}</span></p>
</div>
</td>
</tr>
</tbody>
</table>
</span><span lang="EN-US"><span style="mso-tab-count: 1;">&nbsp; </span></span></p>
<p class="MsoNormal"><span lang="EN-US"><span style="mso-tab-count: 1;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></p>
<p class="MsoNormal" style="text-indent: 18pt;"><span style="font-family: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman';">其中</span><span class="SpellE"><span lang="EN-US">doLog</span></span><span style="font-family: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman';">方法将信息保存到库表中。</span><span lang="EN-US">(</span><span style="font-family: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman';">出于性能考虑，可以采用异步方式保存业务日志到数据库</span><span lang="EN-US">)</span><span style="font-family: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman';">。</span></p>
<p class="MsoNormal"><span lang="EN-US">&nbsp;</span></p>
<p class="MsoNormal" style="margin-left: 18pt; text-indent: -18pt; mso-list: l14 level1 lfo26; tab-stops: list 18.0pt;"><strong style="mso-bidi-font-weight: normal;"><span lang="EN-US" style="mso-fareast-font-family: 'Times New Roman';"><span style="mso-list: Ignore;">2.<span style="font-family: 'Times New Roman';">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span></strong><strong style="mso-bidi-font-weight: normal;"><span style="font-family: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman';">性能监控</span></strong></p>
<p class="MsoNormal"><span lang="EN-US"><span style="mso-tab-count: 1;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>Spring</span><span style="font-family: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman';">本身提供了一个监控拦截器，但功能不是很完善。公司项目架构中设计了一套</span><span lang="EN-US">Monitor</span><span style="font-family: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman';">框架，其功能包含：性能监控</span><span lang="EN-US">(Profiling , Monitoring)</span><span style="font-family: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman';">，访问分析</span><span lang="EN-US">(Analyzing)</span><span style="font-family: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman';">两个方面。</span><strong style="mso-bidi-font-weight: normal;"></strong></p>
<p class="MsoNormal"><span lang="EN-US"><span style="mso-tab-count: 1;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>Monitor</span><span style="font-family: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman';">可切入表示层，业务层</span><span lang="EN-US">BO</span><span style="font-family: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman';">，持久层</span><span lang="EN-US">DAO</span><span style="font-family: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman';">三层。</span><span lang="EN-US">Monitor</span><span style="font-family: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman';">包括以下功能：</span></p>
<p class="MsoNormal" style="margin-left: 42pt; text-indent: -21pt; mso-list: l13 level1 lfo28; tab-stops: list 42.0pt;"><span style="font-family: Symbol; mso-fareast-font-family: Symbol; mso-bidi-font-family: Symbol;"><span style="mso-list: Ignore;">&uml;<span style="font-family: 'Times New Roman';">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><span style="font-family: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman';">按安模块和功能分析性能指标</span></p>
<p class="MsoNormal" style="margin-left: 42pt; text-indent: -21pt; mso-list: l13 level1 lfo28; tab-stops: list 42.0pt;"><span style="font-family: Symbol; mso-fareast-font-family: Symbol; mso-bidi-font-family: Symbol;"><span style="mso-list: Ignore;">&uml;<span style="font-family: 'Times New Roman';">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><span style="font-family: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman';">实时流量监控</span></p>
<p class="MsoNormal" style="margin-left: 42pt; text-indent: -21pt; mso-list: l13 level1 lfo28; tab-stops: list 42.0pt;"><span style="font-family: Symbol; mso-fareast-font-family: Symbol; mso-bidi-font-family: Symbol;"><span style="mso-list: Ignore;">&uml;<span style="font-family: 'Times New Roman';">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><span style="font-family: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman';">按模块和功能分析流量</span></p>
<p class="MsoNormal" style="margin-left: 42pt; text-indent: -21pt; mso-list: l13 level1 lfo28; tab-stops: list 42.0pt;"><span style="font-family: Symbol; mso-fareast-font-family: Symbol; mso-bidi-font-family: Symbol;"><span style="mso-list: Ignore;">&uml;<span style="font-family: 'Times New Roman';">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><span style="font-family: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman';">流量时间分布分析</span></p>
<p class="MsoNormal" style="margin-left: 42pt; text-indent: -21pt; mso-list: l13 level1 lfo28; tab-stops: list 42.0pt;"><span style="font-family: Symbol; mso-fareast-font-family: Symbol; mso-bidi-font-family: Symbol;"><span style="mso-list: Ignore;">&uml;<span style="font-family: 'Times New Roman';">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><span style="font-family: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman';">访问错误分析</span><strong style="mso-bidi-font-weight: normal;"></strong></p>
<p class="MsoNormal"><span lang="EN-US"><span style="mso-tab-count: 1;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman';">这些功能较为全面的为系统管理员提供的系统的各项运行指标，方便用户查找性能瓶颈，进行性能调优。</span></p>
<p class="MsoNormal"><span lang="EN-US"><span style="mso-tab-count: 1;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></p>
<p class="MsoNormal"><span lang="EN-US"><span style="mso-tab-count: 1;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><strong style="mso-bidi-font-weight: normal;"><span style="font-family: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman';">实现原理</span></strong><span style="font-family: 宋体;