<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
  <channel>
    <title>yatell</title>
    <description>The only way to break me is to kill me ,and everything that does not kill me makes me stronger.I just keep fighting! !do it! !!</description>
    <link>http://yate.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>要坚强！</title>
        <author>yate</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://yate.javaeye.com">yate</a>&nbsp;
          链接：<a href="http://yate.javaeye.com/blog/195078" style="color:red;">http://yate.javaeye.com/blog/195078</a>&nbsp;
          发表时间: 2008年05月21日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          一定要坚强！<br />      相信生命的力量！
          <br/>
          <span style="color:red;">
            <a href="http://yate.javaeye.com/blog/195078#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><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><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Wed, 21 May 2008 08:55:23 +0800</pubDate>
        <link>http://yate.javaeye.com/blog/195078</link>
        <guid>http://yate.javaeye.com/blog/195078</guid>
      </item>
      <item>
        <title>近段任务——速录系统开发中.....</title>
        <author>yate</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://yate.javaeye.com">yate</a>&nbsp;
          链接：<a href="http://yate.javaeye.com/blog/193783" style="color:red;">http://yate.javaeye.com/blog/193783</a>&nbsp;
          发表时间: 2008年05月16日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          这段时间一直没上来javaeye写点东西，其实每天都有上网，不过都是有点事了！<br />    从上海回来就没怎么休息过，虽然没什么结果，但自己还是发现了些问题，这段时间也是加重基础方面的学习！回来后两天就是考试，之前一直没有拿过书，估计过是很难了（就看老师放水了），可惜了那两天的自习；之后就是震惊整个华夏大地的地震，12号那天下午2：30正好在考试，考试教室又是在1楼，所以没感觉到，等晚上回到9楼实验室时，大家都在讨论中午的事，整个9楼都晃动了，电脑显示屏幕都有会看不清！接下来就是爆炸式的新闻了，连续看了2天。。又接着就是做些自己力所能及的事情了。<br />     也没什么具体的事做，和几个人在网上一起开始做一个关于速录的系统，可能时间要几个月，不过相当于兼职，每天工作几个小时就够了咯，大概用到SSH，和Ajax（jquery和ext），自己还有很多不懂，哎，边学变请教了！<br />    开始从是从svn检出的时候老是出现错误，到9%就不动了，出现checkout error，，项目主管也远程帮我看了下，还是没办法，最后是什么原因？？我开了卡巴斯基，可能卡巴把那个端口禁了吧，后来发现把卡巴斯基关掉，一下子就ok了，，真的好晕！！<img src="/images/smiles/icon_cry.gif"/><br />    以后每天还是会抽时间来看下javaeye，写点心得什么的。<br />     今天晚上就这些了！！
          <br/>
          <span style="color:red;">
            <a href="http://yate.javaeye.com/blog/193783#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><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, 16 May 2008 21:40:36 +0800</pubDate>
        <link>http://yate.javaeye.com/blog/193783</link>
        <guid>http://yate.javaeye.com/blog/193783</guid>
      </item>
      <item>
        <title>浅谈Java的代理机制</title>
        <author>yate</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://yate.javaeye.com">yate</a>&nbsp;
          链接：<a href="http://yate.javaeye.com/blog/189063" style="color:red;">http://yate.javaeye.com/blog/189063</a>&nbsp;
          发表时间: 2008年05月03日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          　可以说代理是java十分重要的一种机制，另一个当然是属于反射了，jdk中单独讲到了反射API（java.lang.reflect），可能有人认为反射对资源消耗比较厉害，确实也是，反射肯定是要消耗资源的，但也不是什么都要用到反射，所以最佳试验应该是在资源消耗程度和反射的使用程度之间找到一个平衡点，本文并不打算讲反射，关于反射的心得以后再贴出来，自己最近也在折磨折磨<br />   <br />代理可以分为：StaticProxy 和DynamicProxy<br />比如：<br />   Package  xyz；<br />   import java.util.logging.*<br />   public class talkToSomebody{<br />    private Logger logger=Logger.getLogger(this.getClass().getName());<br />    public void talk(String name){<br />        logger.log(Level.INFO,"talking start....");<br />        System.out.println("Hi!ni hao,"+name);<br />        logger.log(Level.INFO,"talking ends....");<br />        }<br />    }<br /><br />很显示，你需要talk其他人，其实就只有一个句话是关键的，"Hi!ni hao XXX" ,这才是需要关系的，或者叫核心业务（这个次可能有点牵强），但如果要记录你和哪些人交谈过，哪时候开始的，哪时候结束的，日志功能就是实现这个，这属于业务逻辑，把业务逻辑和核心业务放到了一起，如果哪天不需要记录了，怎么办?得重新改源代码，甚至如果客户只提供给你编译过的class或接口，你会很郁闷的！<br /><br />    解决方法：<br />用Proxy机制，其实代理就像一个中介机构，我自己突然有什么事（或者不愿意），找中介机构去做，当然你得出钱给中介机构。<br />public interface ITalk{<br />    public void talk(String name);<br />}<br /><br />可以把这个看做你的要求，中介机构必须按照你的要求来做，你才会付钱给中介机构；<br /><br />public class TalkToSomebody implements ITalk{<br />     public void talk(String name){<br />        System.out.println("Hi,ni hao,"+name);<br />     }<br />}<br /><br />不错，中介机构是按照我的要求实现的，结果没错！<br /><br /><br />public class StaticProxyTalk Implements ITalk{<br />    private Logger logger=Logger.getLogger(this.getClass().getName());<br />    private ITalk  somebody;<br />    public  StaticProxyTalk(ITalk somebody){<br />            this.somebody=somebody;<br />    }<br />    public void talk(String name){<br />           log("talking start....");<br />           somebody.talk(name);<br />           log("talking ending...");<br />    }<br />    private void log(String message){<br />           logger.log(Level.INFO,message)<br />    }<br /><br />感觉好多了，以后我不需要中介服务了，不去找他就行，现在看下这个中介机构做得怎么样，达到我的要求了没？<br /><br /><br />public class TestProxy{<br />    public static void main(String []args){<br />         ITalk proxy=new StaticProxyTalk(new TalkToSomebody());<br />         proxy.talk("HuYong");<br />    }<br />}<br /><br />是的，，它做到了，我可以付钱给它了。。<br /><br />但是问题还是存在，如果我有N多事都不想自己做（比较懒），我得每一件都去找中介机构吗？能不能一类的就找一次就够了勒？？<br /><br />看下面的一个LogTalk：<br />import java.lang.reflect.InvocationHandler;<br />import java.lang.reflect.Method;<br />import java.lang.reflect.Proxy;<br />import java.util.logging.Level;<br />import java.util.logging.Logger;<br /><br />/**<br /> * @author HuYong Email:yate7571@hotmail.com<br /> */<br />public class LogTalk implements InvocationHandler {<br />	private Logger logger = Logger.getLogger(this.getClass().getName());<br /><br />	private Object object;<br /><br />	public Object bind(Object object) {<br />		this.object = object;<br />		return Proxy.newProxyInstance(object.getClass().getClassLoader(),<br />				object.getClass().getInterfaces(), this);<br /><br />	}<br /><br />	public Object invoke(Object proxy, Method method, Object[] args)<br />			throws Throwable {<br />		Object result = null;<br />		try {<br />			log("method starts ...." + method);<br />			result = method.invoke(object, args);<br />			log("method ends...." + method);<br />		} catch (Exception e) {<br />			log(e.toString());<br />		}<br />		return result;<br />	}<br /><br />	private void log(String message) {<br />		logger.log(Level.INFO, message);<br />	}<br /><br />}<br /><br />只要我需要做的事是一类事（可以理解一类事物），我就可以先和中介机构签好活动，我以后所有的你帮我做就是了，我只需要结构就ok了，中介机构也承诺，只要你给我们的都符合这个约定（都是Object),我就接了。<br /><br />也来测试下：<br />public class TestDynamicProxy{<br />    public static void main(String []args){<br />         LogTalk dynamicproxy=new LogTalk();<br />         ITalk proxy=(ITalk)dynamicproxy.bind(new TalkToSomebody());<br />         proxy.talk("YangYi");<br />    }<br />}<br /><br />可以通过了，，以后这些事你都可以帮我做了，我列个清单给中介机构有哪些事了，这些事你就帮我做了，如果哪天有事不需要做了，我打电话给你取消那项就可以了，不影响其他事情的继续做下去，也不需要去改动相关的约定了。。<br /><br /><br />关于LogTalk的讲解：<br />public static Object newProxyInstance(ClassLoader loader,<br />                                      Class&lt;?>[] interfaces,<br />                                      InvocationHandler h)<br />                               throws IllegalArgumentException<br />返回一个指定接口的代理类实例，该接口可以将方法调用指派到指定的调用处理程序<br /><br /><br />public Object bind(Object object) {<br />		this.object = object;<br />		return Proxy.newProxyInstance(object.getClass().getClassLoader(),<br />				object.getClass().getInterfaces(), this);<br /><br /><br />绑定，只要是Object的子类就可以绑定（呵呵，所有的都是Object的子类勒！） <br /><br />总结：这其实是AOP的最底层实现，AOP的的好处就是用到了代理，把各种业务逻辑分离开来了，不管是核心要处理的还是作为辅助功能（或者测试）的业务逻辑，比如日志作为一个切面可以去测试每个方法是否都执行了，用AOP就不需要去改动任何核心业务，如果不要了，就不指定Pointcut就可以了(关于AOP的各种术语可以参考 spring reference），这应该算是一种思想的转变。<br /><br />补充：可能我用到的"核心业务"，和其他"业务逻辑"理解有点不同，个人理解是这样的：核心业务就是我需要去关心的，这是核心。其他业务逻辑（很多书上说是与业务逻辑无关的系统服务逻辑）比如说日志，安全方面等，只是做为核心的一个外壳，没有外壳核心照样可以存活，只是没有那么美观了。
          <br/>
          <span style="color:red;">
            <a href="http://yate.javaeye.com/blog/189063#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><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sat, 03 May 2008 15:46:48 +0800</pubDate>
        <link>http://yate.javaeye.com/blog/189063</link>
        <guid>http://yate.javaeye.com/blog/189063</guid>
      </item>
      <item>
        <title>Spring XML配置的12个技巧(引述)</title>
        <author>yate</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://yate.javaeye.com">yate</a>&nbsp;
          链接：<a href="http://yate.javaeye.com/blog/188911" style="color:red;">http://yate.javaeye.com/blog/188911</a>&nbsp;
          发表时间: 2008年05月02日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          作者：Jason Zhicheng Li 出处：CSDN <br />  <br />Spring是一个强有力的java程序框架，其被广泛应用于java的程序中。它用POJO提供了企业级服务。Spring利用依赖注入可以获得简单而有效的测试能力。Spring beans，依赖关系，以及服务所需要的bean都将在配置文件中予以描述，配置文件一般采用XML格式。然而XML配置文件冗长而不易使用，在你进行一个使用了大量bean的大项目中它将变得难以阅读和控制。<br /><br />在这篇文章中我将给你展示12种的有关Spring XML配置文件的最佳技巧。它们中的一些具有更多的实际意义，而不仅是最好的技巧。请注意另外一些因素，例如域模型的设计，会影响到XML配置，但是这篇文章更关注于XML配置的可读性和可操控性。<br /><br />1． 避免使用自动装配<br /><br />Spring可以通过bean类的自省来实现自动装配依赖，这样的话你就不必明确地描述bean的属性或者构造函数的参数。根据属性名称活匹配类型，bean属性可以自动进行装配。而构造函数可以根据匹配类型自动装配。你甚至可以设置自动装配进行自动侦测，这样Spring替你就会选择一个合适的机制。请看下面的例子：<br /><br />Spring可以通过bean类的自省来实现自动装配依赖，这样的话你就不必明确地描述bean的属性或者构造函数的参数。根据属性名称活匹配类型，bean属性可以自动进行装配。而构造函数可以根据匹配类型自动装配。你甚至可以设置自动装配进行自动侦测，这样Spring替你就会选择一个合适的机制。请看下面的例子：<br /><br />    &lt;bean id="orderService"<br /><br />        class="com.lizjason.spring.OrderService"<br /><br />        autowire="byName"/><br /><br />OrderService类的属性名被用来和容器中的一个bean实例进行匹配。自动装配会默默的保存一些类型信息并降低混乱。然而，由于它会牺牲掉这种配置的直观性和可维护性，你在实际的项目中将不会用到它。许多指南和陈述材料都把它吹捧为Spring的一个非常cool的特性，而没有提到它的这个缺点。依我之见，就像Spring的对象池一样，它更多了一些商业味道。它看起来好像可以使XML配置文件更精简一些，但实际上却增加其复杂性，尤其是在你的较大规模的工程中已经定义了很多bean的时候更是如此。Spring允许你混合使用自动和手动装配，但是这种矛盾会使XML配置更加的令人费解。<br /><br />2． 使用命名规范<br /><br />和Java编码的理念一样，在项目中始终用清晰的，描述性的，一致的命名规范对开发人员理解XML配置非常有用。拿bean ID举例来说，你可以遵循Java类中属性的命名规范。比如说，OrderServiceDAO的bean ID应该是orderServiceDAO。对于大项目来说，在bean ID前加包名来作为前缀。<br /><br />3． 使用简化格式<br /><br />简化格式有利于减少冗余，因为它把属性值和引用作为属性，而不是子元素。看下面的例子：<br /><br />    &lt;bean id="orderService"<br />        class="com.lizjason.spring.OrderService"><br />        &lt;property name="companyName"><br />            &lt;value>lizjason&lt;/value><br />        &lt;/property><br />        &lt;constructor-arg><br />            &lt;ref bean="orderDAO"><br />        &lt;/constructor-arg><br />    &lt;/bean><br />以上程序可以重新以简化格式书写为：<br /><br />   &lt;bean id="orderService"<br />        class="com.lizjason.spring.OrderService"><br />        &lt;property name="companyName"<br />            value="lizjason"/><br />        &lt;constructor-arg ref="orderDAO"/><br />    &lt;/bean><br />简化格式在1.2版本时已经可用了，但请注意不存在&lt;ref local="...">这种简化格式不仅可以较少你的代码输入量，而且可以使XML配置更加的清晰。当你的配置文件中存在大量的bean定义时，它可以显著地提高可读性。 <br /><br />4． 尽量使用type而不是index去解决构造函数参数的匹配问题<br /><br />当构造函数中有多个同类型的参数时，Spring只允许你使用从0开始的index或者value标签来解决这个问题。请看下面的例子：<br /><br />   &lt;bean id="billingService"<br />        class="com.lizjason.spring.BillingService"><br />        &lt;constructor-arg index="0" value="lizjason"/><br />        &lt;constructor-arg index="1" value="100"/><br />    &lt;/bean><br />最好用type属性取代上面的做法：<br /><br />    &lt;bean id="billingService"<br />        class="com.lizjason.spring.BillingService"><br />        &lt;constructor-arg type="java.lang.String"<br />            value="lizjason"/><br />        &lt;constructor-arg type="int" value="100"/><br />    &lt;/bean><br />用index可以稍微减少冗余，但是它更容易出错且不如type属性可读性高。你应该仅在构造函数中有参数冲突时使用index。 <br /><br />5． 如可能，尽量复用bean定义<br /><br />Spring提供了一种类似于继承的机制来降低配置信息的重复并使XML配置更加的简单。一个子bean可以从它的父bean继承配置信息，本质上这个父bean就像它的子bean的一个模板。这是一个在大型项目中必须使用的特性。所有你要做的就是把父bean的abstract属性置为true，并在子bean中加以引用。例如：<br /><br />    &lt;bean id="abstractService" abstract="true"<br />        class="com.lizjason.spring.AbstractService"><br />        &lt;property name="companyName"<br />            value="lizjason"/><br />    &lt;/bean><br /> <br />    &lt;bean id="shippingService"<br />        parent="abstractService"<br />        class="com.lizjason.spring.ShippingService"><br />        &lt;property name="shippedBy" value="lizjason"/><br />    &lt;/bean><br />shippingService bean继承了abstractService bean的属性companyName的值lizjason。注意，如果你为bean声名一个class或工厂方法，这个bean将会默认为abstract <br /><br />6． 尽量使用ApplicationContext装配bean，而不是用import<br /><br />像Ant脚本中imports一样，Spring的import 元素对于模块化bean的装配非常有用，例如：<br /><br />   &lt;beans><br />        &lt;import resource="billingServices.xml"/><br />        &lt;import resource="shippingServices.xml"/><br />        &lt;bean id="orderService"<br />            class="com.lizjason.spring.OrderService"/><br />    &lt;beans><br />然而，比起在XML中用imports预装配这些bean，利用ApplicationContext来配置它们将更加灵活，也可以使XML配置更加的易于管理。你可以像下面这样传递一个bean定义数组到ApplicationContext的构造函数中： <br /><br />    String[] serviceResources =<br /><br />        {"orderServices.xml",<br /><br />        "billingServices.xml",<br /><br />        "shippingServices.xml"};<br /><br />ApplicationContext orderServiceContext = new<br /><br />ClassPathXmlApplicationContext(serviceResources);<br /><br /> 7． 用id来标识bean<br /><br />你可以用id或名字作为bean的标识。用id可读性较差，但是它可以影响XML分析器使bean的reference有效。如果id由于XML IDREF约束而无法使用，你可以用name作为bean的标识。XML IDREF约束是指id必须以字母开始(或者是在XML声名了的一个标点符号)，后面可以是字母，数字，连字符，下划线，冒号或full stops(不知道怎么翻译好)。在实际应用中很少会遇到XML IDREF约束问题。<br /><br />8． 在开发阶段使用依赖检查<br /><br />你可以为bean的dependency-check属性设置一个值来取代默认的none，比如说simple，objects或者all，这样的话容器将替你做依赖有效性的检查。当一个bean的所有属性(或者某些属性目录)都被明确设置，或利用自动装配时将会非常有用。<br /><br />   &lt;bean id="orderService"<br />        class="com.lizjason.spring.OrderService"<br />        dependency-check="objects"><br />        &lt;property name="companyName"<br />            value="lizjason"/><br />        &lt;constructor-arg ref="orderDAO"/><br />    &lt;/bean><br />在这个例子中，容器将确保这些属性不是privitives或者保证collections是为orderService bean设置的。为所有的bean设置默认的依赖检查是可能的，但这个特性由于有些bean的属性不需要设置而很少使用。 <br /><br />9． 为每个配置文件加一个描述注释<br /><br />在XML配置文件中最好使用有描述性的id和name，而不是成堆的注释。另外，加一个文件描述头将会非常有用，这个描述可以概括文件中定义的bean。另一个选择，你可以在description元素中加入描述信息。例如：<br /><br />    &lt;beans><br />        &lt;description><br />            This file defines billing service<br />            related beans and it depends on<br />            baseServices.xml,which provides<br />            service bean templates...<br />        &lt;/description><br />        ...<br />    &lt;/beans><br />用description元素的一个好处就是工具可以很容易的把描述信息从这个元素中提取出来。<br /><br />10． 和team members沟通变更<br /><br />当你修改java源码后，要确保更改了配置文件中的相应部分并把这个情况告知你的team members。XML配置文件也是代码，它们是程序的重要组成部分，但它们很难阅读和维护。大多数时间里，你需要同时看XML配置文件和java代码才能知道是怎么回事。<br /><br />11． setter注入和构造函数注入，优先使用前者<br /><br />Spring提供了三种注入方式：构造函数注入，setter注入和方法注入。一般我们使用前两种。<br /><br />   &lt;bean id="orderService"<br />        class="com.lizjason.spring.OrderService"><br />        &lt;constructor-arg ref="orderDAO"/><br />    &lt;/bean><br /> <br />    &lt;bean id="billingService"<br />        class="com.lizjason.spring.BillingService"><br />        &lt;property name="billingDAO"<br />            ref="billingDAO"><br />    &lt;/bean><br />在这个例子中，orderService bean用了构造函数注入，而BillingService bean用了setter注入。构造函数注入可以确保bean正确地构建，但是setter注入更加的灵活和易于控制，特别是当class有多个属性并且它们中的一些是可选的情况是更是如此。<br /><br />12． 不要滥用注入<br /><br />就像前面提到的，Spring的ApplicationContext可以替你创建java对象，但不是所有的java对象都应该通过注入创建。例如，域对象就不应该通过ApplicationContext创建。Spring是一个优秀的框架，但是考虑到可读性和可操控性，基于XML配置的配置会在定义很多bean的时候出现麻烦。过渡使用依赖注入将会使XML配置更加的复杂和冗长。切记，当使用高效的IDE时，例如Eclipse and IntelliJ，java代码更加的易于阅读，维护和管理比使XML文件<br /><br />结论<br /><br />XML是Spring流行的配置格式。存在大量bean定义时，基于XML的配置会变得冗长而不易使用。Spring提供了丰富的配置选项。适当地使用这些选项可以使XML配置更加的清晰，但其它的一些选项，例如自动装配，可能会降低可读性和可维护性。参考本文中提到的这些技巧可能会帮助你创建干净而易读的XML配置文件。<br /><br />原稿位置：<br /><br />http://www.onjava.com/pub/a/onjava/2006/01/25/spring-xml-configuration-best-practices.html
          <br/>
          <span style="color:red;">
            <a href="http://yate.javaeye.com/blog/188911#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><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><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Fri, 02 May 2008 20:20:31 +0800</pubDate>
        <link>http://yate.javaeye.com/blog/188911</link>
        <guid>http://yate.javaeye.com/blog/188911</guid>
      </item>
      <item>
        <title>spring AOP介绍2</title>
        <author>yate</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://yate.javaeye.com">yate</a>&nbsp;
          链接：<a href="http://yate.javaeye.com/blog/188910" style="color:red;">http://yate.javaeye.com/blog/188910</a>&nbsp;
          发表时间: 2008年05月02日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          Spring Framework中的面向方面编程（AOP），第二部分<br /> <br />  <br />2008-03-21 作者:Russell Miles 出处:dev2dev.bea.com.cn<br /> <br />  <br />在本系列的第一部分，我介绍了如何实现面向方面领域的“HelloWorld”：跟踪和记录方面。利用Spring框架所提供的面向方面编程(Aspect-Oriented Programming，AOP)功能，您看到了如何使用before-、after-和基于异常的通知，以及如何使用基于正则表达式的简单切入点。跟踪和记录方面提供了非常不错的上手例子，而本文将进一步介绍一种新的通知形式：around通知。 <br /><br />比起第一部分中介绍的那些通知类型，around形式的通知是一种更具侵入性也更强大的面向对象概念。本文将描述around通知的每个特性，以便您可以在自己的Spring AOP应用程序中正确地使用它。在本文最后，我将向您展示如何使用around通知来截获和改变应用程序中各个特性相互作用的方式，以便实现Cuckoo's Egg（杜鹃的蛋）面向方面设计模式。<br /><br />概述Spring AOP、IoC和代理<br /><br />在第一部分，我们快速浏览了Spring的一些AOP特性，而没有阐明Spring如何实现AOP的细节。要理解Spring框架如何运转，尤其是它如何实现其AOP功能，首先您要明白，Spring是一个依赖于控制反转(Inversion of Control，IoC)设计模式的轻量级框架。<br /><br />注意：本文的目的不是要深入介绍IoC模式，介绍IoC只是为了使您明白该设计模式是如何影响Spring AOP实现的。有关IoC模式的更详细的介绍请参见本文末尾的参考资料。<br /><br />IoC设计模式的出现已经有一段时间了。一个最明显的例子就是J2EE架构本身。随着企业开发尤其是J2EE平台的出现，应用程序开始依赖于由外部容器所提供的一些特性，比如bean创建、持久性、消息传递、会话以及事务管理。<br /><br />IoC引入了一个新概念：由组件构成的框架，它与J2EE容器有许多类似之处。IoC框架分离了组件所依赖的功能，并且，根据Sam Newman文章中的说法，提供了“连接组件的‘胶水’”。<br /><br />对组件所依赖特性的控制 被反转 了，这样外部框架就可以尽可能透明地提供这些特性了。IoC模式真正意识到了从传统的由依赖于功能的组件来负责这些功能，到由独立的框架来配置和提供这些功能的方式转变。<br /><br />图1显示了一些构成IoC模式的不同组件角色的例子。<br /><br /><br />图1. 没有对BusinessLogic bean应用方面时的顺序图.<br /><br />图字：<br /><br />Component：组件<br /><br />Provides Facilities：提供功能<br /><br />Relies on and conforms to：依赖于并服从<br /><br />Manages the services the framework can then use to provide facilities：管理框架随后可以用来提供功能的服务<br /><br />Service：服务<br /><br />Your Component：您的组件<br /><br />IoC Framework：IoC框架<br /><br />External services：外部服务<br /><br />IoC模式使用3种不同的方法来解除组件与服务控制的耦合：类型1、类型2和类型3。<br /><br />类型1：接口注入<br />这是大部分J2EE实现所使用的方法。组件显式地服从于一组接口，带有关联的配置元数据，以便允许框架对它们进行正确的管理。 <br />类型2：Setter注入<br />外部元数据被用来配置组件相互作用的方式。在第一部分中，我们就是使用这种IoC方法利用springconfig.xml文件来配置Spring组件的。 <br />类型3：构造函数注入<br />组件（包括构造组件时要用的参数）注册到框架，而框架提供组件的实例以及所有要应用的指定功能。 <br />IoC在组件开发和企业开发中越来越受欢迎。IoC的实际例子包括传统的J2EE解决方案，比如：JBoss、Apache基金会的Avalon项目以及本文的Spring框架。实际上，Spring框架构建于IoC模式的基础上是为了帮助将它的轻量级功能注入到它的相关应用程序的组件中。<br /><br />那么IoC对于Spring AOP有何意义呢？Spring的IoC特性是使用IoC springconfig.xml配置文件对应用程序应用方面的推动因素之一。springconfig.xml配置文件通知Spring框架运行时有关应用程序的组件要被注入的功能类型的信息，所以自然轻量级的AOP功能就以同样的方式应用了。然后Spring使用代理模式围绕现有的类和bean实现指定的AOP功能。<br /><br />图2显示了Spring及其IoC框架如何使用代理对象提供AOP功能（根据springconfig.xml文件中的IoC配置。）<br /><br /><br />图2. springconfig.xml配置文件改变了Spring框架IoC，以便随后向第一部分中的一个顺序图提供AOP代理（单击图像查看大图）<br /><br />在本系列下面的部分，您将不断看到现在包含在顺序图中的代理对象。这只是为了说明对于Spring AOP来说没有“魔法”，实际上只有一个面向对象设计模式的良好例子。<br /><br />回到AOP：使用around通知的积极方面<br /><br />在第一部分，您看到了如何使用Spring AOP来实现跟踪和记录方面。跟踪和记录都是“消极”方面，因为它们的出现并不会对应用程序的其他行为产生影响。它们都使用了消极的before和after形式的通知。<br /><br />但是如果您希望改变应用程序的常规行为呢？例如说，您希望重写一个方法？这样的话，您就需要使用更积极的around形式的通知。<br /><br />第一部分的简单例子应用程序包括IbusinessLogic接口、BusinessLogic类和MainApplication类，如下所示：<br /><br />public interface IBusinessLogic<br />{<br />  public void foo();<br />}<br /><br /><br />public class BusinessLogic <br />  implements IBusinessLogic<br />{<br />  public void foo() <br />  {<br />     System.out.println(<br />       "Inside BusinessLogic.foo()");<br />  }<br />}<br /><br />import org.springframework.context.ApplicationContext;<br />import org.springframework.context.support.FileSystemXmlApplicationContext;<br /><br />public class MainApplication<br />{<br />  public static void main(String [] args)<br />  {<br />    // Read the configuration file<br />    ApplicationContext ctx = <br />      new FileSystemXmlApplicationContext(<br />        "springconfig.xml");<br /><br />    //Instantiate an object<br />    IBusinessLogic testObject = <br />      (IBusinessLogic) ctx.getBean(<br />        "businesslogicbean");<br /><br />    // Execute the public <br />    // method of the bean<br />    testObject.foo();<br />  }<br />}<br /><br />要对一个BusinessLogic类的实例彻底重写对foo()方法的调用，需要创建around通知，如下面的AroundAdvice类所示：<br /><br />import org.aopalliance.intercept.MethodInvocation;<br />import org.aopalliance.intercept.MethodInterceptor;<br /><br />public class AroundAdvice <br />   implements MethodInterceptor<br />{<br />   public Object invoke(<br />      MethodInvocation invocation)<br />      throws Throwable<br />   {<br />      System.out.println(<br />         "Hello world! (by " + <br />         this.getClass().getName() + <br />         ")");<br /><br />      return null;<br />   }<br />}<br /><br />要在Spring中用作around通知，AroundAdvice类必须实现MethodInterceptor接口和它的invoke(..)方法。每当截获到方法的重写，invoke(..)方法就会被调用。最后一步是改变包含在应用程序的springconfig.xml文件中的Spring运行时配置，以便可以对应用程序应用AroundAdvice。<br /><br />&lt;?xml version="1.0" encoding="UTF-8"?><br />&lt;!DOCTYPE beans PUBLIC  "-//SPRING//DTD BEAN//EN"<br />    "http://www.springframework.org/dtd/spring-beans.dtd"><br /><br />&lt;beans><br /><br />   &lt;!-- Bean configuration --><br />   &lt;bean id="businesslogicbean"<br />   class="org.springframework.aop.framework.ProxyFactoryBean"><br />      &lt;property name="proxyInterfaces"><br />         &lt;value>IBusinessLogic&lt;/value><br />      &lt;/property><br />      &lt;property name="target"><br />         &lt;ref local="beanTarget"/><br />      &lt;/property><br />      &lt;property name="interceptorNames"><br />         &lt;list><br />            &lt;value>theAroundAdvisor&lt;/value><br />         &lt;/list><br />         &lt;/property><br />   &lt;/bean><br />   &lt;!-- Bean Classes --><br />   &lt;bean id="beanTarget"<br />   class="BusinessLogic"/><br /><br />   &lt;!-- Advisor pointcut definition for around advice --><br />   &lt;bean id="theAroundAdvisor"<br />      class="org.springframework.aop.support.RegexpMethodPointcutAdvisor"><br />      &lt;property name="advice"><br />         &lt;ref local="theAroundAdvice"/><br />      &lt;/property><br />      &lt;property name="pattern"><br />         &lt;value>.*&lt;/value><br />      &lt;/property><br />   &lt;/bean><br />	<br />   &lt;!-- Advice classes --><br />   &lt;bean id="theAroundAdvice"<br />      class="AroundAdvice"/><br /><br />&lt;/beans><br /><br />根据该springconfig.xml配置文件，theAroundAdvisor截获所有对BusinessLogic类的方法的调用。接下来，theAroundAdvisor被关联到theAroundAdvice，表明当截获一个方法时，就应该使用在AroundAdvice类中指定的通知。既然已经指定了around通知的正确配置，下一次执行MainApplication类时，BusinessLogic bean的foo()方法就会被截获并重写，如图3所示：<br /><br /><br />图3. 使用around通知重写对BusinessLogic类中的foo()方法的调用<br /><br />前面的例子显示，BusinessLogic类中的foo()方法可以通过AroundAdvice类中的invoke(..)方法彻底重写。原来的foo()方法完全不能被invoke(..)方法调用。如果希望从around通知内调用foo()方法，可以使用proceed()方法，可从invoke(..)方法的MethodInvocation参数中得到它。<br /><br />public class AroundAdvice <br />   implements MethodInterceptor<br />{<br />   public Object invoke(<br />      MethodInvocation invocation) <br />      throws Throwable<br />   {<br />      System.out.println(<br />         "Hello world! (by " + <br />         this.getClass().getName() + <br />         ")");<br /><br />      invocation.proceed();<br /><br />      System.out.println("Goodbye! (by " + <br />         this.getClass().getName() + <br />         ")");<br /><br />      return null;<br />   }<br />}<br /><br />图4显示了对proceed()的调用如何影响操作的顺序（与图3所示的初始around通知执行相比较）。<br /><br /><br />图4. 从around通知内使用proceed()调用原来的方法<br /><br />当调用proceed()时，实际是在指示被截获的方法（在本例中是foo()方法）利用包含在MethodInvocation对象中的信息运行。您可以通过调用MethodInvocation类中的其他方法来改变该信息。<br /><br />您可能希望更改包含在MethodInvocation类中的信息，以便在使用proceed()调用被截获的方法之前对被截获方法的参数设置新值。<br /><br />通过对MethodInvocation对象调用getArguments()方法，然后在返回的数组中设置其中的一个参数对象，最初传递给被截获的方法的参数可以被更改。<br /><br />如果IbusinessClass和BusinessLogic类的foo()方法被更改为使用整型参数，那么就可以将传递给被截获的调用的值由在AroundAdvice的notify(..)方法中传递改为在foo(int)中传递。<br /><br />public class AroundAdvice <br />   implements MethodInterceptor<br />{<br />   public Object invoke(<br />      MethodInvocation invocation) <br />      throws Throwable<br />   {<br />      System.out.println(<br />         "Hello world! (by " + <br />         this.getClass().getName() + <br />         ")");<br />      <br />      invocation.getArguments()[0] = new Integer(20);<br />      <br />      invocation.proceed();<br />      <br />      System.out.println(<br />         "Goodbye! (by " + <br />         this.getClass().getName() + <br />         ")");<br />      <br />      return null;<br />   }<br />}<br /><br />在本例中，被截获的方法的第一个形参被假设为int。实参本身是作为对象传递的，所以通过将其包装在Integer类实例中的方法，基本的int类型的形参被改为对应数组中的新值。如果您将该参数设置为一个非Integer对象的值，那么在运行时就会抛出IllegalArgumentException异常。<br /><br />您还将注意到，invoke(..)方法必须包含一个return语句，因为该方法需要返回值。但是，被重写的foo()方法并不返回对象，所以invoke(..)方法可以以返回null结束。如果在foo()方法不需要的情况下，您仍然返回了一个对象，那么该对象将被忽略。<br /><br />如果foo()方法确实需要返回值，那么需要返回一个与foo()方法的初始返回类型在同一个类或其子类中的对象。如果foo()方法返回一个简单类型，例如，一个integer，那么您需要返回一个Integer类的对象，当方法被重写时，该对象会自动由AOP代理拆箱，如图5所示：<br /><br /><br />图5. around通知的装箱和自动拆箱<br /><br />图字：<br /><br />Object invoke：对象调用<br /><br />The integer return value is boxed in a Integer object in the AroundAdvice and then unboxed by the AOP Proxy：整型返回值被装箱在AroundAdvic通知的一个Integer对象中，然后由AOP代理拆箱。<br /><br />面向方面编程还是一个比较新的领域，尤其是与衍生出它的面向对象编程相比。设计模式通常被认为是常见问题的通用解决方案，因为面向方面发展的时间还不长，所以已发现的面向方面设计模式比较少。<br /><br />此处要介绍的是一种正在浮现的模式，即Cuckoo's Egg设计模式。该模式还有其他的叫法，它在面向对象领域的对等体包括模仿对象（Mock Object）和模仿测试（Mock Testing），甚至代理模式也与它有一些类似之处。<br /><br />Cuckoo's Egg面向方面设计模式可以被定义为应用程序上下文中功能部件的透明和模块化的置换。就像杜鹃偷偷地把自己的蛋放在另一种鸟的巢中一样，Cuckoo's Egg设计模式用一个替代功能部件实现置换现有的功能部件,而使造成的干扰尽可能少。<br /><br />这种置换的实现方式可以是静态的、动态的、部分的、完全的，针对一个对象的多个部分，或针对多个组件。使用面向方面的方法可以透明地实现功能部件的置换，而无需对应用程序的其余部分进行更改。要置换应用程序中现有功能部件的替代功能部件就是“杜鹃的蛋”。图6显示了Cuckoo's Egg设计模式中的主要组成元素。<br /><br /><br />图6. Cuckoo's Egg设计模式中的主要组成元素<br /><br />图字：<br /><br />Application：应用程序<br /><br />Component：组件<br /><br />Replacement Feature：替代功能部件<br /><br />Component 1 and 2 together encompass a distinct feature of the software：组件1和2共同包含了软件的一个独立的功能部件<br /><br />The Cuckoo's Egg pattern transparently replaces an existing feature of the software：Cuckoo's Egg模式透明地置换了软件现有的功能部件<br /><br />Before the pattern is applied：应用该模式前<br /><br />After the pattern is applied：应用该模式后<br /><br />Cuckoo's Egg设计模式依赖于around通知的概念。您需要借助于积极的和侵入性的around通知来截获并有效置换应用程序中现有的功能部件。<br /><br />有关Cuckoo's Egg设计模式的更多信息，以及AspectJ中的一个可选实现，请参见《AspectJ Cookbook》（O'Reilly，2004年12月出版）。<br /><br />要使用Spring AOP实现Cuckoo's Egg设计模式，需要声明一个around通知来截获所有对要置换的功能部件的调用。与hot-swappable target sources（Spring AOP的一个功能部件，将在本系列的另一篇文章中介绍）不同，around通知的显式使用使得Cuckoo's Egg实现可以有效地跨越对象边界（因此也可以跨越bean边界）进行整个功能部件的置换，如图7所示。<br /><br /><br />图7. 一个跨越bean边界的组件<br /><br />图字：<br /><br />A feature crosses the boundaries of BusinessLogic and BusinessLogic2 by depending on behavior supplied separately by the two beans：一个功能部件通过依赖于由BusinessLogic和BusinessLogic2各自提供的行为而跨越了这两个bean的边界<br /><br />下面的代码显示了一个具有两个bean的简单应用程序，其中有一个功能部件跨越了该应用程序的多个方面。要置换的功能部件可以被视为包含IBusinessLogic bean中的foo()方法和IBusinessLogic2 bean中的bar()方法。IBusinessLogic2 bean中的baz()方法不是 该功能部件的一部分，所以不进行置换。<br /><br />public interface IBusinessLogic<br />{<br />   public void foo();<br />}<br /><br />public interface IBusinessLogic2<br />{<br />   public void bar();<br />   <br />   public void baz();<br />}<br /><br />该例子的完整源代码可在本文末尾的参考资料小节中下载。<br /><br />此处，ReplacementFeature类扮演了“杜鹃的蛋”的角色，它提供了将被透明地引入应用程序的替代实现。ReplacementFeature类实现了所有在该类引入时要被置换的方法。<br /><br />public class ReplacementFeature<br />{<br />   public void foo()<br />   {<br />      System.out.println(<br />         "Inside ReplacementFeature.foo()");<br />   }<br />   <br />   public void bar()<br />   {<br />      System.out.println(<br />         "Inside ReplacementFeature.bar()");<br />   }<br />}<br /><br />现在需要声明一个around通知来截获对跨越bean的功能部件的方法调用。CuckoosEgg类提供了某种around通知来检查被截获的方法，并将适当的方法调用传递给ReplacementFeature类的实例。<br /><br />public class CuckoosEgg implements MethodInterceptor<br />{<br />   public ReplacementFeature replacementFeature =<br />       new ReplacementFeature();<br />   <br />   public Object invoke(MethodInvocation invocation)<br />       throws Throwable<br />   {<br />      if (invocation.getMethod().getName().equals("foo"))<br />      {<br />         replacementFeature.foo();<br />      }<br />      else<br />      {<br />         replacementFeature.bar();<br />      }<br />      <br />      return null;<br />   }<br />}<br /><br />因为与Spring框架关系密切，Cuckoo's Egg设计的详细信息被放在springconfig.xml配置文件中。对springconfig.xml文件的更改将确保所有对IbusinessLogic和IBusinessLogic2 bean的foo()方法和bar()方法的调用都将被截获，并传递给CuckoosEgg类的around通知。<br /><br />   ...<br />   <br />   &lt;!--CONFIG--><br />   &lt;bean id="businesslogicbean" <br />      class="org.springframework.aop.framework.ProxyFactoryBean"><br />      &lt;property name="proxyInterfaces"><br />         &lt;value>IBusinessLogic&lt;/value><br />      &lt;/property><br />      &lt;property name="target"><br />         &lt;ref local="beanTarget"/><br />      &lt;/property><br />      &lt;property name="interceptorNames"><br />         &lt;list><br />            &lt;value>theCuckoosEggAdvisor&lt;/value><br />         &lt;/list><br />      &lt;/property><br />   &lt;/bean><br />   <br />   &lt;bean id="businesslogicbean2" <br />      class="org.springframework.aop.framework.ProxyFactoryBean"><br />      &lt;property name="proxyInterfaces"><br />         &lt;value>IBusinessLogic2&lt;/value><br />      &lt;/property><br />      &lt;property name="target"><br />         &lt;ref local="beanTarget2"/><br />      &lt;/property><br />      &lt;property name="interceptorNames"><br />         &lt;list><br />            &lt;value>theCuckoosEgg2Advisor&lt;/value><br />         &lt;/list><br />      &lt;/property><br />   &lt;/bean><br /><br />   &lt;!--CLASS--><br />   &lt;bean id="beanTarget" class="BusinessLogic"/><br />   &lt;bean id="beanTarget2" class="BusinessLogic2"/><br />   <br />   &lt;!--ADVISOR--><br />   &lt;bean id="theCuckoosEggAdvisor" <br />      class="org.springframework.aop.support.RegexpMethodPointcutAdvisor"><br />      &lt;property name="advice"><br />         &lt;ref local="theReplacementFeaturePart1Advice"/><br />      &lt;/property><br />      &lt;property name="pattern"><br />         &lt;value>IBusinessLogic.*&lt;/value><br />      &lt;/property><br />   &lt;/bean><br />   <br />   &lt;bean id="theCuckoosEgg2Advisor" <br />      class="org.springframework.aop.support.RegexpMethodPointcutAdvisor"><br />      &lt;property name="advice"><br />         &lt;ref local="theReplacementFeaturePart2Advice"/><br />      &lt;/property><br />      &lt;property name="pattern"><br />         &lt;value>IBusinessLogic2.bar*&lt;/value><br />      &lt;/property><br />   &lt;/bean><br />   <br />   &lt;!--ADVICE--><br />   &lt;bean id="theReplacementFeaturePart1Advice" class="CuckoosEgg"/><br />   &lt;bean id="theReplacementFeaturePart2Advice" class="CuckoosEgg"/><br />   <br />   ...<br /><br />当使用修改后的springconfig.xml文件运行例子应用程序时，要替换的、被指定为功能部件的一部分的方法调用完全被截获并传递给ReplacementFeature类。<br /><br />通常，即使在同一个实现环境中，我们也可以用不同的方法来实现同一种设计模式。实现上例的另一种方法是实现两个独立的通知。<br /><br />最后需要注意的是，使用Cuckoo's Egg设计模式置换的功能部件，不管它是跨越bean的还是在一个类中，它的生命周期与它所置换的功能部件的目标生命周期匹配。在上例中这没什么问题，因为只有一个功能部件实例被置换了，而且唯一的Cuckoo's Egg通知只维护一个替代功能部件。<br /><br />这个例子非常简单，而在实践中，您很可能必须处理大量需要用各自的Cuckoo's Egg实例置换的功能部件实例。在这种情况下，单个的方面实例需要被关联到单个的要置换的功能部件实例。本系列的下一篇文章将会考虑方面生命周期的用法，届时将解决这个问题。<br /><br />结束语<br /><br />本文介绍了如何在Spring框架内谨慎使用around形式的通知。around形式的通知常用于实现Cuckoo's Egg设计模式时，所以我们引入了一个例子来说明如何使用Spring AOP实现这种面向方面设计模式。<br /><br />在本系列的第三部分中，您将看到如何使用Spring框架中其他的AOP基本概念。这些概念包括：控制方面生命周期、使用基于introduction通知的积极方面改变应用程序的静态结构，以及使用control flow切入点实现对方面编织的更细微的控制。<br /><br />参考资料<br /><br />Spring框架教程——向您展示Spring框架的内部运作方式 <br />本文的完整源代码 <br />Spring Java/J2EE框架 <br />“Comparing the Inversion of Control and Dependency Injection Design Patterns” <br />IoC模式概述 <br />Spring框架参考文档第5章——介绍Spring中的所有AOP特性 <br />原文出处 An Introduction to Aspect-Oriented Programming with the Spring Framework, Part 2 http://www.onjava.com/pub/a/onjava/2004/10/20/springaop2.html
          <br/>
          <span style="color:red;">
            <a href="http://yate.javaeye.com/blog/188910#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><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Fri, 02 May 2008 20:18:48 +0800</pubDate>
        <link>http://yate.javaeye.com/blog/188910</link>
        <guid>http://yate.javaeye.com/blog/188910</guid>
      </item>
      <item>
        <title>spring AOP介绍1</title>
        <author>yate</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://yate.javaeye.com">yate</a>&nbsp;
          链接：<a href="http://yate.javaeye.com/blog/188909" style="color:red;">http://yate.javaeye.com/blog/188909</a>&nbsp;
          发表时间: 2008年05月02日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          Spring Framework中的面向方面编程（AOP），第一部分<br /> <br />作者:Russell Miles 出处:dev2dev.bea.com.cn<br /> <br />　　作为这个介绍Spring框架中的面向方面编程(Aspect-Oriented Programming，AOP)的系列的第一部分，本文介绍了使您可以使用Spring中的面向方面特性进行快速开发的基础知识。使用跟踪和记录方面（面向方面领域的HelloWorld）作为例子，本文展示了如何使用Spring框架所独有的特性来声明切入点和通知以便应用方面。本系列的第二部分将更深入地介绍如何运用Spring中的所有通知类型和切入点来实现更实用的方面和面向方面设计模式。对于AOP的更一般性的介绍，请查看ONJava站点上Graham O'Regan的文章，“Introduction to Aspect-Oriented Programming”。<br /><br />　　本文的目的不是要介绍构成模块化J2EE系统——即Spring框架——的所有重要元素，我们将只把注意力放在Spring所提供的AOP功能上。由于Spring的模块化设计方法，我们可以只使用该框架的AOP元素，而无需对构成Spring框架的其他模块做太多考虑。<br /><br />　　在AOP方面，Spring提供了什么？<br /><br />　　“它的目标不是提供最完善的AOP实现（虽然Spring AOP非常强大）；而是要提供AOP实现与Spring IoC的紧密集成，以便帮助解决企业应用中的常见问题。”<br /><br />　　Spring Framework参考文档<br /><br />　　为了实现这个目标，Spring框架目前支持一组AOP概念，从切入点到通知。本文将展示如何使用Spring框架中所实现的如下AOP概念：<br /><br />　　通知（Advice）：如何将before通知、afterReturning通知和afterThrowing通知声明为bean。<br /><br />　　切入点（Pointcut）：如何声明静态切入点逻辑以将XML Spring Bean Configuration文件中的所有内容联系在一起。<br /><br />　　Advisor：关联切入点定义与通知bean的方式。<br /><br />　　设置场景：一个简单的例子应用程序<br /><br />　　“一般而言，Spring并不是预描述的。虽然使用好的实践非常容易，但是它避免强制推行一种特定的方法。”<br /><br />　　Spring Framework参考文档<br /><br />　　要试用Spring框架的AOP功能，首先我们要创建一个简单的Java应用程序。IbusinessLogic接口和BusinessLogic类为Spring框架中的bean提供了简易构件块。虽然该接口对于我们的简单应用程序逻辑来说不是必需的，但是它是Spring框架所推荐的良好实践。<br /><br />public interface IBusinessLogic<br />{<br />　public void foo();<br />}<br /><br />public class BusinessLogic<br />implements IBusinessLogic<br />{<br />　public void foo()<br />　{<br />　　System.out.println("Inside BusinessLogic.foo()");<br />　}<br />} <br /><br />　　可以编写MainApplication类，借此练习BusinessLogic bean的公有方法。<br /><br />import org.springframework.context.ApplicationContext;<br />import org.springframework.context.support.FileSystemXmlApplicationContext;<br /><br />public class MainApplication<br />{<br />　public static void main(String [] args)<br />　{<br />　　// Read the configuration file<br />　　ApplicationContext ctx =new FileSystemXmlApplicationContext("springconfig.xml");<br /><br />　　//Instantiate an object<br />　　IBusinessLogic testObject =(IBusinessLogic) ctx.getBean("businesslogicbean");<br /><br />　　// Execute the public<br />　　// method of the bean<br />　　testObject.foo();<br />　}<br />} <br /><br />　　在BusinessLogic类及其关联接口中没有什么需要注意的。但是，MainApplication类初始化BusinessLogic对象的方式很有意思。通过使用ctx.getBean("businesslogicbean")调用，MainApplication将加载和管理BusinessLogic类的bean实例的任务转交给了Spring框架。<br /><br />　　允许Spring控制BusinessLogic bean的初始化，这使得Spring运行时有机会在bean被返回给应用程序之前执行J2EE系统所需的所有与bean相关的管理任务。然后Spring运行时配置可以决定对bean应用哪些任务和模块。该配置信息由一个XML文件提供，类似于下面所示的：<br /><br />＜?xml version="1.0" encoding="UTF-8"?＞<br />＜!DOCTYPE beans PUBLIC<br />"-//SPRING//DTD BEAN//EN"<br />"http://www.springframework.org/dtd/spring-beans.dtd"＞<br /><br />＜beans＞<br /><br />　＜!-- Bean configuration --＞<br />　＜bean id="businesslogicbean" class="org.springframework.aop.framework.ProxyFactoryBean"＞<br />　　＜property name="proxyInterfaces"＞<br />　　　＜value＞IBusinessLogic＜/value＞<br />　　＜/property＞<br />　　＜property name="target"＞<br />　　　＜ref local="beanTarget"/＞<br />　　＜/property＞<br />　＜/bean＞<br />　＜!-- Bean Classes --＞<br />　＜bean id="beanTarget" class="BusinessLogic"/＞<br />　＜/beans＞<br />＜/BEANS＞ <br /><br />　　该配置文件，即springconfig.xml，指定要加载一个接口与IbusinessLogic相匹配的bean。该bean随后被关联到BusinessLogic实现类。看起来好像是费了很大力气只为了加载一个简单的bean并调用一个方法，但是您要知道，这个配置文件只是使Spring框架可以透明地对应用程序应用其组件的众多特性的一个体现。<br /><br />　　图1显示了基本的顺序图：MainApplication原样执行，没有应用方面。<br /><br /><br /><br /><br /><br />图1.没有对BusinessLogic bean应用方面时的顺序图<br /><br />　　应用方法跟踪（Method Tracing）方面<br /><br />　　可能最基本的方面就是方法跟踪方面了。这可能是您找得到的最简单的方面了，因此它是研究新的AOP实现的一个很好的起点。<br /><br />　　方法跟踪方面在一个目标应用程序内捕获对所跟踪的方法的调用以及方法的返回值，并以某种方式显示这种信息。在AOP中，通知的before和after类型用于捕获这些类型的联结点，因为这两种通知可以在方法调用联结点之前或之后触发。使用Spring框架，方法跟踪方面的before通知是在TracingBeforeAdvice类中声明的。 <br /><br />import java.lang.reflect.Method;<br />import org.springframework.aop. MethodBeforeAdvice;<br /><br />public class TracingBeforeAdvice<br />implements MethodBeforeAdvice<br />{<br />　public void before(Method m,Object[] args,Object target)<br />　throws Throwable<br />　{<br />　　System.out.println("Hello world! (by " +this.getClass().getName() +")");<br />　}<br />} <br /><br />　　类似地，after通知可以在TracingAfterAdvice类中声明。<br /><br />import java.lang.reflect.Method;<br />import org.springframework.aop.AfterReturningAdvice;<br /><br />public class TracingAfterAdvice<br />implements AfterReturningAdvice<br />{<br />　public void afterReturning(Object object,Method m,Object[] args,Object target)<br />　throws Throwable<br />　{<br />　　System.out.println("Hello world! (by " +this.getClass().getName() +")");<br />　}<br />} <br /><br />　　这两个类都通过实现Spring框架的适当通知接口而表示了特定的通知。每种类型的通知都指定实现before(..)或afterReturning(..)方法，以便使Spring运行时可以告诉通知适当的联结点会在何时出现。值得注意的是，TracingAfterAdvice实际上是从AfterReturningAdvice扩展而来的，表示只有在联结点在无异常的情况下获得返回值时才运行通知。<br /><br />　　为了将通知与应用程序中的适当联结点关联起来，必须对springconfig.xml进行一些修改。<br /><br />＜?xml version="1.0" encoding="UTF-8"?＞<br />＜!DOCTYPE beans PUBLIC<br />"-//SPRING//DTD BEAN//EN"<br />"http://www.springframework.org/dtd/spring-beans.dtd"＞<br /><br />＜beans＞<br /><br />＜!-- Bean configuration --＞<br />＜bean id="businesslogicbean" class="org.springframework.aop.framework.ProxyFactoryBean"＞<br />　＜property name="proxyInterfaces"＞<br />　　＜value＞IBusinessLogic＜/value＞<br />　＜/property＞<br />　＜property name="target"＞<br />　　＜ref local="beanTarget"/＞<br />　＜/property＞<br />　＜property name="interceptorNames"＞<br />　　＜list＞<br />　　　＜value＞theTracingBeforeAdvisor＜/value＞<br />　　　＜value＞theTracingAfterAdvisor＜/value＞<br />　　＜/list＞<br />　＜/property＞<br />＜/bean＞<br />＜!-- Bean Classes --＞<br />＜bean id="beanTarget"<br />class="BusinessLogic"/＞<br /><br />＜!-- Advisor pointcut definition for before advice --＞<br />＜bean id="theTracingBeforeAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor"＞<br />　＜property name="advice"＞<br />　　＜ref local="theTracingBeforeAdvice"/＞<br />　＜/property＞<br />　＜property name="pattern"＞<br />　　＜value＞.*＜/value＞<br />　＜/property＞<br />＜/bean＞<br /><br />＜!-- Advisor pointcut definition for after advice --＞<br />＜bean id="theTracingAfterAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor"＞<br />　＜property name="advice"＞<br />　　＜ref local="theTracingAfterAdvice"/＞<br />　＜/property＞<br />　＜property name="pattern"＞<br />　　＜value＞.*＜/value＞<br />　＜/property＞<br />＜/bean＞<br /><br />＜!-- Advice classes --＞<br />＜bean id="theTracingBeforeAdvice" class="TracingBeforeAdvice"/＞<br />＜bean id="theTracingAfterAdvice" class="TracingAfterAdvice"/＞<br />＜/beans＞ <br /><br />　　theTracingBeforeAdvisor和theTracingAfterAdvisor advisor被添加到前面所声明的businesslogicbean。每个advisor都可能截获所有bean所关联到的联结点。Advisor本身就是bean，而它唯一的作用就是将切入点定义与通知bean关联起来。本例中的切入点定义是在静态对象层次结构中指定相关联结点的正则表达式。<br /><br />　　因为本例中使用了org.springframework.aop.support.RegexpMethodPointcutAdvisor切入点advisor，切入点逻辑是使用正则表达式指定的。正则表达式用于识别公有接口对IbusinessLogici接口的联结点。下面是一些可以用来指定IBusinessLogic接口上的不同联结点集合的正则表达式例子：<br /><br />　　 .* ：该表达式选择advisor所关联到的一个或多个bean上的所有联结点。<br /><br />　　 ./IBusinessLogic/.foo ：该表达式只选择IbusinessLogic接口上的foo()方法的联结点。如果是advisor所关联到的bean，则该表达式只选择IBusinessLogic接口上的联结点。<br /><br />　　springconfig.xml文件中最后的bean声明指定实现通知bean的类。<br /><br />　　既然已经指定了跟踪方面的正确配置，那么下一次执行MainApplication时，这些方面就会在初始化过程中被编织进去，而BusinessLogic bean中的所有方法都将被跟踪，如图2所示。<br /><br /><br /><br />　　图2. 方法跟踪方面应用到BusinessLogic bean之后的顺序图<br /><br />　　方面的重用<br /><br />　　可以对方法跟踪方面进行扩展，提供一个稍微复杂的记录（Logging）方面。记录方面提供了一个很不错的重用例子，因为记录方面所需的许多特性都已经包含在方法跟踪方面中了。<br /><br />　　在本例中，记录方面扩展了方法跟踪方面，以便显示附加的与（在应用程序的执行过程中）所引发的异常有关的信息。<br /><br />　　要完全使用记录方面，需要对应用程序做一些更改。BusinessLogicException异常类提供了一个可以由IBusinessLogicInterface接口和BusinessLogic实现类新增的void bar()方法引发的异常。<br /><br />public class BusinessLogicException<br />extends Exception<br />{}<br /><br />public interface IBusinessLogic<br />{<br />　public void foo();<br /><br />　public void bar()<br />　throws BusinessLogicException;<br />}<br /><br />public class BusinessLogic<br />implements IBusinessLogic<br />{<br />　public void foo()<br />　{<br />　　System.out.println("Inside BusinessLogic.foo()");<br />　}<br /><br />　public void bar()<br />　throws BusinessLogicException<br />　{<br />　　System.out.println("Inside BusinessLogic.bar()");<br />　　throw new BusinessLogicException();<br />　}<br />} <br /><br />　　MainApplication类现在将对void bar()方法进行一次额外的调用，并处理选中的、可能由该方法引发的异常。<br /><br />import org.springframeworkcontext.ApplicationContext;<br />import org.springframework.context.support.FileSystemXmlApplicationContext;<br /><br />public class MainApplication<br />{<br />　public static void main(String [] args)<br />　{<br />　　// Read the configuration file<br />　　ApplicationContext ctx = new FileSystemXmlApplicationContext( "springconfig.xml");<br /><br />　　//Instantiate an object<br />　　IBusinessLogic testObject =(IBusinessLogic) ctx.getBean("businesslogicbean");<br /><br />　　//Execute the public methods of the bean<br />　　testObject.foo();<br /><br />　　try<br />　　{<br />　　　testObject.bar();<br />　　}<br />　　catch(BusinessLogicException ble)<br />　　{<br />　　　System.out.println( "Caught BusinessLogicException");<br />　　}<br />　}<br />} <br /><br />　　来自方法跟踪方面的TracingBeforeAdvice和TracingAfterAdvice通知可以整体重用。LoggingThrowsAdvice类为新的异常记录提供了通知。<br />import org.springframework.aop.ThrowsAdvice;<br />import java.lang.reflect.Method;<br /><br />public class LoggingThrowsAdvice<br />implements ThrowsAdvice<br />{<br />　public void afterThrowing(Method method,Object[] args,Object target,Throwable subclass)<br />　{<br />　　System.out.println("Logging that a " +subclass +"Exception was thrown.");<br />　}<br />}<br /> <br /><br />　　应用记录方面的最后一步是修改springconfig.xml配置文件，使其包含新添加的LoggingThrowsAdvice通知。<br /><br />　　图3显示了运行MainApplication并使用Spring框架应用了记录方面的UML顺序图。<br /><br /><br /><br />　　图3. 记录方面应用到BusinessLogic bean之后的顺序图<br /><br />　　此处的记录方面清楚地说明了如何重用现有方面以及如何在Spring框架中使用通知的throws形式。通过为before和after通知声明新的通知来重写现有的方法跟踪方面实现，可以实现更复杂的记录方面，记录到更复杂的记录框架，比如LOG4J。<br /><br />　　结束语<br /><br />　　本文展示了使用Spring框架中的基本AOP结构所应用的一些简单方面。在本系列的下一篇文章中，我们将介绍一些更实用的方面，探讨方面的生命周期，使用Spring框架的around通知，并使用Spring来应用AOP模式。
          <br/>
          <span style="color:red;">
            <a href="http://yate.javaeye.com/blog/188909#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/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</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, 02 May 2008 20:17:49 +0800</pubDate>
        <link>http://yate.javaeye.com/blog/188909</link>
        <guid>http://yate.javaeye.com/blog/188909</guid>
      </item>
      <item>
        <title>动态代理的形象解释，不错！</title>
        <author>yate</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://yate.javaeye.com">yate</a>&nbsp;
          链接：<a href="http://yate.javaeye.com/blog/188908" style="color:red;">http://yate.javaeye.com/blog/188908</a>&nbsp;
          发表时间: 2008年05月02日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          本文来自：http://www.uml.org.cn/sjms/200602212.htm<br /><br />代理模式、动态代理和面向方面<br /> <br /> <br />    代理的意思很好理解，它借鉴了我们日常所用的代理的意思：就是本来该自己亲自去做的某件事，由于某种原因不能直接做，而只能请人代替你做，这个被你请来做事的人就是代理。比如过春节要回家，由于你要上班，没时间去买票，就得票务中介代你购买，这就是一种代理模式。这个情景可以形象的描述如下： <br />class：火车站 <br />{ <br />        卖票： <br />       {……} <br />} <br />    火车站是卖票的地方，我们假设只能在火车站买到票。卖票的动作实质是火车站类完成的。 <br />Class：票务中介 <br />{ <br />        卖票： <br />        { <br />               收中介费； <br />              火车站.卖票； <br />} <br />} <br />    顾客找票务中介买票的时候，调用票务中介.卖票。票务中介其实做了两件事，一是去火车站买票，二是不能白帮你卖票，肯定要收中介费。而你得到的好处是不用直接去火车站买票，节省了买票的时间用来上班。 <br />    以上我们简单模拟了代理模式的情景和为什么要使用代理模式，下面我们以一个例子来具体分析一下JAVA中的代理模式。 <br />    假设有一个信息管理系统，用些用户有浏览信息的权限，有些用户有浏览、添加和修改信息的权限，还有些用户有除了上述的权限，还有删除信息的权限，那么我们最容易想到的做法如下： <br />public class ViewAction <br />{ <br />        //由userId计算权限 <br />        …… <br />        String permission = ……; <br />       if(permission.equals(Constants.VIEW)) <br />        { <br />               System.out.println(“You could view the information……”); <br />               …… <br />} <br />} <br />    其他的动作都和浏览信息的动作差不多。我们来看这样的类，很容易看出它的一些缺点来：第一、它把权限计算和动作执行都放在一个类里，两者的功能相互混在一起，容易造成思路的混乱，而且修改维护和测试都不好；一句话来说，它不满足单一职责原则。第二是客户调用的时候依赖具体的类，造成扩展和运行期内的调用的困难，不满足依赖颠倒原则。 <br />    既然有这么多的问题，我们有必要对该类进行重新设计。其实大家早已想到，这个类应该使用代理模式。是啊，和我们买火车票的动作一样，动作类不能直接执行那个动作，而是要先检查权限，然后才能执行；先检查权限，后执行的那各类其实就是一个代理类，修改后的代码如下： <br />public interface Action <br />{ <br />        public void doAction(); <br />} <br />   首先是设计一个接口，用来满足依赖颠倒原则。 <br />Public class ViewAction implements Action <br />{ <br />        public void doAction() <br />        { <br />               //做View的动作 <br />               System.out.println(“You could view the information……”); <br />               …… <br />} <br />} <br />    这个类跟火车站一样，是动作的真实执行者。 <br />Public class ProxyViewAction implements Action <br />{ <br />        private Action action = new ViewAction(); <br />        public void doAction() <br />        { <br />               //调用权限类的方法取得用户权限 <br />               if(Permission.getPermission(userId).equals(Constants.VIEW)) <br />               { <br />                      action.doAction(); <br />} <br />} <br />} <br />    这是代理类，很容易理解。在我们的ProxyViewAction类中，除了做了客户真正想要做的动作：doAction()以外，还进行了额外的动作检查用户的权限。而作核心动作doAction()是在一个干干净净的类：ViewAction中进行，这个类只做核心动作，对其他的不关心，满足了单一职责原则。 <br />    客户端通过调用代理类来执行动作，而代理类一是将权限判断和动作的执行分离开来，满足了单一职责原则；二是实现了一个接口，从而满足了依赖颠倒原则。比第一个思路好了很多。 <br />    代理又被称为委派，说的是代理类并不真正的执行那个核心动作，而是委派给另外一个类去执行，如ProxyView类中，ProxyView类并没有真正执行doAction()方法，而是交给ViewAction类去执行。 <br />    我们再来看代理类ProxyViewAction，可以看到它不仅依赖于接口Action，而且依赖于具体的实现ViewAction。这样对我们的系统扩展很不利，比如我们有Add动作、Delete动作、Modify动作等等，我们需要对每一个动作都写一个代理类，而这些代理类都做同样的事情，先进行权限判断，然后再委派。所以我们需要对这些代理再进行一次抽象，让它只依赖接口Action，而不依赖于具体的实现。 <br />    要实现这样的想法，我们需要将代理类中的具体实现提走，让代理的使用者在运行期提供具体的实现类，即所谓的依赖注入，如下： <br />Public class ProxyAction implements Action <br />{ <br />        private Action action; <br />        public ProxyAction(Action action) <br />        { <br />               this.action = action; <br />} <br />        public void doAction() <br />        { <br />               //调用权限类的方法取得用户权限 <br />               if(Permission.getPermission(userId).equals(action.getClass().getName())) <br />               { <br />                      action.doAction(); <br />} <br />} <br />} <br />    这样，我们就将所有实现了Action接口的实现使用一个代理类来代理它们。除了ViewAction类能用，以后扩展的AddAction、       ModifyAction、DeleteAction类等等，都可以使用一个代理类：ProxyAction。 <br />    而我们的客户端类似如下： <br />Action action = ProxyAction(new ViewAction); <br />Action.doAction(); <br />    通过对代理类的依赖注入，我们使得代理类初步有了一定扩展性。但是我们还要看到，这个代理类依赖于某一个确定的接口。这仍然不能满足我们的实际要求，如我们的系统的权限控制一般是整个系统级的，这样系统级的权限控制，我们很难在整个系统里抽象出一个统一的接口，可能会有多个接口，按照上面的代理模式，我们需要对每一个接口写一个代理类，同样，这些类的功能都是一样的。这显然不是一个好地解决办法。 <br />    基于上面的原因，我们需要解决一个系统在没有统一的接口的情况下，对一些零散的对象的某一些动作使用代理模式的问题。JAVA API为我们引入了动态代理或动态委派的技术。 <br />    动态代理的核心是InvocationHandler接口，要使用动态代理就必须实现该接口。这个接口的委派任务是在invoke(Object proxy, Method m, Object[] args)方法里面实现的： <br />//在调用核心功能之前作一些动作 <br />…… <br />//调用核心功能 <br />m.invoke(obj, args); <br />//在调用核心功能以后做一些动作 <br />…… <br />    我们可以看到动态代理其实用的是反射机制来调用核心功能的：m.invoke(obj, args);正是这种反射机制的使用使得我们调用核心功能更加灵活，而不用依赖于某一个具体的接口，而是依赖于Object对象。 <br />    下面我们来具体看看动态代理或动态委派如何使用： <br />public class ProxyAction implements InvocationHandler { <br />private Object action; <br />public ProxyAction(Object action) <br />{ <br />       this.action = action; <br />} <br />public static Object getInstance(Object action) <br />{ <br />        return Proxy.newProxyInstance(action.getClass().getClassLoader(), <br />action.getClass().getInterfaces(),new ProxyAction(action)); <br />} <br />  <br />public Object invoke(Object proxy, Method m, Object[] args) <br />               throws Throwable { <br />        <br />        Object result; <br />  <br />       try { <br />                      //在委派之前作动作，如权限判断等 <br />           System.out.println("before method " + m.getName()); <br />                      //进行委派 <br />           result = m.invoke(action, args); <br />  <br />       } catch (InvocationTargetException e) { <br />  <br />           throw e.getTargetException(); <br />  <br />       } catch (Exception e) { <br />  <br />           throw new RuntimeException("unexpected invocation exception: " <br />  <br />                  + e.getMessage()); <br />  <br />       } finally { <br />                      //在委派之后做动作 <br />           System.out.println("after method " + m.getName()); <br />  <br />       } <br />  <br />       return result; <br />  <br />　 <br />} <br />  <br />} <br />  <br />    这个代理类，首先是实现了InvocationHandler接口；然后在getInstance（）方法里得到了代理类的实例；在invoke（）方法里实现代理功能，也很简单。 <br />    下面我们来看客户端： <br />Action action = (Action)ProxyAction.getInstance(new ViewAction()); <br />Action.doAction(); <br />    我们可以看到代理类对接口的依赖也转移到了客户端上，这样，代理类不依赖于某个接口。对于同样的代理类ProxyAction，我们也可以有如下的客户端调用： <br />Engine engine = (Engine)ProxyAction.getInstance(new EngineImpl()); <br />Engine.execute(); <br />    只要engineImpl类实现了Engine接口，就可以像上面那样使用。 <br />    现在我们可以看到，动态代理的确是拥有相当的灵活性。但我们同时也看到了，这个代理类写起来比较麻烦，而且也差不多每次都写这样千篇一律的东西，只有委派前的动作和委派后的动作在不同的代理里有着不同，其他的东西都需要照写。如果这样的代理类写多了，也会有一些冗余代理。需要我们进一步优化，这里我们使用模板方法模式来对这个代理类进行优化，如下： <br />public abstract class BaseProxy implements InvocationHandler { <br />private Object obj; <br />protected BaseProxy(Object obj) <br />{ <br />       this.obj = obj; <br />} <br />public static Object getInstance(Object obj,InvocationHandler instance) <br />{ <br />        return Proxy.newProxyInstance(obj.getClass().getClassLoader(), <br />obj.getClass().getInterfaces(),instance); <br />} <br />  <br />public Object invoke(Object proxy, Method m, Object[] args) <br />               throws Throwable { <br />        // TODO Auto-generated method stub <br />        Object result; <br />  <br />       try { <br />  <br />           System.out.println("before method " + m.getName()); <br />           this.doBegin(); <br />  <br />           result = m.invoke(obj, args); <br />  <br />       } catch (InvocationTargetException e) { <br />  <br />           throw e.getTargetException(); <br />  <br />       } catch (Exception e) { <br />  <br />           throw new RuntimeException("unexpected invocation exception: " <br />  <br />                  + e.getMessage()); <br />  <br />       } finally { <br />  <br />           System.out.println("after method " + m.getName()); <br />           this.doAfter(); <br />  <br />       } <br />  <br />       return result; <br />  <br />　 <br />} <br />public abstract void doBegin(); <br />public abstract void doAfter(); <br />  <br />} <br />    这样，代理的实现类只需要关注实现委派前的动作和委派后的动作就行，如下： <br />public class ProxyImpl extends BaseProxy { <br />protected ProxyImpl(Object o) <br />{ <br />       super(o); <br />} <br />public static Object getInstance(Object foo) <br />{ <br />        return getInstance(foo,new ProxyImpl(foo)); <br />} <br />  <br />//委派前的动作 <br />public void doBegin() { <br />        // TODO Auto-generated method stub <br />       System.out.println("begin doing....haha"); <br />  <br />} <br />  <br />//委派后的动作 <br />public void doAfter() { <br />        // TODO Auto-generated method stub <br />       System.out.println("after doing.....yeah"); <br />  <br />} <br />  <br />} <br />    从上面的代码，我们可以看出代理实现类的确是简单多了，只关注了委派前和委派后的动作，这是我们作为一个代理真正需要关心的。 <br />    至此，代理模式和动态代理已经告一段落。我们将动态代理引申一点说开去，来作为这篇文章的蛇足。 <br />    这个话题就是面向方面的编程，或者说AOP。我们看上面的ProxyImpl类，它的两个方法doBegin()和doAfter()，这是做核心动作之前和之后的两个截取段。正是这两个截取段，却是我们AOP的基础。在OOP里，doBegin()，核心动作，doAfter()这三个动作在多个类里始终在一起，但他们所要完成的逻辑却是不同的，如doBegin()可能做的是权限，在所有的类里它都做权限；而在每个类里核心动作却各不相同；doAfter()可能做的是日志，在所有的类里它都做日志。正是因为在所有的类里，doBegin()或doAfter()都做的是同样的逻辑，因此我们需要将它们提取出来，单独分析、设计和编码，这就是我们的AOP的思想。 <br />    这样说来，我们的动态代理就能作为实现AOP的基础了。好了，就说这么多，关于AOP技术，我们可以去关注关于这方面的知识。
          <br/>
          <span style="color:red;">
            <a href="http://yate.javaeye.com/blog/188908#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/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</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, 02 May 2008 20:08:34 +0800</pubDate>
        <link>http://yate.javaeye.com/blog/188908</link>
        <guid>http://yate.javaeye.com/blog/188908</guid>
      </item>
      <item>
        <title>《boss town》</title>
        <author>yate</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://yate.javaeye.com">yate</a>&nbsp;
          链接：<a href="http://yate.javaeye.com/blog/188905" style="color:red;">http://yate.javaeye.com/blog/188905</a>&nbsp;
          发表时间: 2008年05月02日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          其实几个月前一直都有看第一财经的《boss town》，后来又没怎么看了，今天在电脑里找了几个出来，以后还是有时间看看，反正一个也就47分钟，还是比看电影划算多了。个人是比较爱看这些人物自传的，比如说《boss town》《鲁豫有约》《华人纵横天下》，当然可能这些成功人士给我呈现的是他们成功的一面，他们有过的失败，有过的心酸没有表现出来，但我们至少可以意识这点，现在市场都是基于全球的竞争，特别是要想做一个跨国的企业或者集团的话，这点会显得更加突出。 <br />  今天看的是大成集团的韩家寰，一个1岁就患了小儿麻痹症证"斗鱼",确实，现在想要在一个传统行业能够做得这么成功，这么大，而且能够坚持下去，已经不是一般人能有所为。<br />   听了王石的那段评论，比较有感触，大概是以下这个意思：中国的企业家还是第1代，往往就把做大做为目标，而台湾的企业家已经是第2代了，他们不再是把大做为根本目标，是一种结果了，显得比较成熟了。<br />  当然韩家寰是从事的是一个家族企业，可能与我们大多数人的情况不一样，也不可能有这样的条件，但有点可以意识到的是传统行业其实也不错（大成1年的营业额就有160亿），以后选择自己的工作的时候不一定要在新型的行业，传统的行业照样可以，当然自己的兴趣是首先要考虑的，如果有一个亲切的boss，有N多要好的同事，做得比较开心，何乐而不为勒！<img src="/images/smiles/icon_smile.gif"/>
          <br/>
          <span style="color:red;">
            <a href="http://yate.javaeye.com/blog/188905#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><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><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Fri, 02 May 2008 19:37:25 +0800</pubDate>
        <link>http://yate.javaeye.com/blog/188905</link>
        <guid>http://yate.javaeye.com/blog/188905</guid>
      </item>
      <item>
        <title>spring数据绑定功能</title>
        <author>yate</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://yate.javaeye.com">yate</a>&nbsp;
          链接：<a href="http://yate.javaeye.com/blog/188873" style="color:red;">http://yate.javaeye.com/blog/188873</a>&nbsp;
          发表时间: 2008年05月02日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          1,主要是用到BeanWrapper，实际中可以用BeanWrapperImp（自定义一个数据绑定实现）<br />2，比如有一个公司，里面一个职员，得到公司的名称，地址等属于公司的属性，又要得到属于职员的属性，可以用BeanWrapper实现比如：<br /><br />                     Company company=new Company();<br />		BeanWrapper bw=new BeanWrapperImpl(company);<br />		bw.setPropertyValue("name", "Chinasoft");<br />		bw.setPropertyValue("addr[0]", "BeiJing");<br />		bw.setPropertyValue("addr[1]","ShangHai");<br />		bw.setPropertyValue("addr[2]", "ChangSha");<br />		bw.setPropertyValue("huyong",new Employee());<br />		bw.setPropertyValue("huyong.tel[home]", "07317450XXX");<br />		bw.setPropertyValue("huyong.tel[mobile]", "1311752XXXX");<br />		bw.setPropertyValue("huyong.salary", "10000");<br /><br /><br />当然Company和Employee两个类必须有对应属性的get和set方法<br />3，大概就是一个bean中的属性，通过BeanWrapper后，可以用这种方式setPropertyValue("属性"，“值”)绑定起来，，具体的怎样绑定的已经让BeanWrapperImpl去实现了，我们只需要关联属性字段就可以了，Hibernate里面的集合赋值有点类似的味道！<br /><br /><br />4，PropertyEditor：当然springIoc加载的ApplicationContext.xml，把配置文件作为流读，里面所有的属性和值肯定都是以String的方式，但我们写bean的时候肯定有其他属性，比如其他基本类型，引用类型，我们可能没意识到这点，是怎么转变过来的勒，，其实是spring内建的PropertyEditor帮了我们，在BeanWrapperImp的实现类中已经注册好了，它们是作为可配置项实现的，所以我们也可以自己实现自己想要的装换，比如日期格式的问题，可以像这样2008-05-02变为2008/05/02等的。<br />自定实现需要扩展PropertyEditorSupport类，并覆盖setAsText(),在这个setAsText()方法里可以实现自己的格式等<br /><br />配置bean：a，使用ConfigurableBeanFactory的registerCustomEditor()方法进行自定义PropertyEditor的注册，这不够灵活，不推荐使用<br />b，使用CustomEditorConfigurer对bean进行后期处理，处理过程终实现对自定义的PropertyEditor的绑定<br /><br />总结：spring的PropertyEditor使用主要用在下面两个方面：<br />1，BeanFactory中，为Bean的属性赋值（一般从String（xml）转化为其他类型)<br />2，进行用户请求的参数转变（用户提交的参数都是string，当然上传文件等的除外，这里也要到了PropertyEditor进行对象类型的转换）<br /><br /><br />具体代码可以参考SSH集成整合宝典的spring核心讲解
          <br/>
          <span style="color:red;">
            <a href="http://yate.javaeye.com/blog/188873#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</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, 02 May 2008 17:21:58 +0800</pubDate>
        <link>http://yate.javaeye.com/blog/188873</link>
        <guid>http://yate.javaeye.com/blog/188873</guid>
      </item>
      <item>
        <title>《时代》全球最具影响力的100人出炉了！</title>
        <author>yate</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://yate.javaeye.com">yate</a>&nbsp;
          链接：<a href="http://yate.javaeye.com/blog/188828" style="color:red;">http://yate.javaeye.com/blog/188828</a>&nbsp;
          发表时间: 2008年05月02日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          今天在time官方网站上看到今年的最具全球影响力的100人，胡锦涛还是延续去年还在榜上，马英九也上了，还有Cisco的CEOJohn Chambers，美国的希拉里和奥巴马都上了，这次中国国务院副秘书长 Lou Jiwei(楼继伟)也上了，表彰在经济方面的贡献！<br />本次100人一共分为Leaders & Revolutionaries，Heroes & Pioneers，Scientists & Thinkers，Builders & Titans，Artists & Entertainers五个方面，大概每个部分20个人(有点差别）<br /><br />胡锦涛的评价是基辛格写的，原文如下：<br /><br />Hu Jintao<br />By Henry A. Kissinger<br />Hu Jintao is the first Chinese leader who grew up in the aftermath of the revolution that established communism in 1949. He inherits its tradition, but he has gone far beyond it. In a marked evolution from Mao Zedong, Hu, 65, has proclaimed the goal of a harmonious society whose components work together by consensus rather than direction. It is a principle he has tried to apply to international affairs as well. <br /><br />Having met with Hu on many occasions, I invariably found him thoughtful, extremely well prepared and very courteous. His mastery of the subject matter seems to make small talk unnecessary to him. <br /><br />In foreign policy, Hu undoubtedly believes that China is entitled to a role appropriate to its growing potential. He is not a crusader, however, and will try to accommodate the imperatives of both sides. There is much public discussion of an evolving adversarial U.S.-China relationship. This poses a challenge to statesmanship on both sides of the Pacific. Any American President is obliged to articulate the deepest values of our people, including human rights. Any Chinese President needs to reflect the necessities of his society, including the territorial integrity of a united China. The challenge for the future is whether they can find a way to work together, recognizing that an adversarial relationship will drain both sides, that many current problems can only be solved on a global basis and that a peaceful and prosperous world requires Sino-American cooperation. <br /><br />Kissinger is a former U.S. Secretary of State <br /><br /><br />楼继伟的评价如下：<br />Lou Jiwei<br />By Stephen S. Roach<br />Can one fund manager make a difference to China and the rest of the world? That question will be answered by Lou Jiwei, 57, China's former Vice Minister of Finance and one of the country's most seasoned financial operators. It is a daunting challenge: organizing the largest investment-fund start-up ever when the world could well be in the worst financial crisis since the 1930s. <br /><br />In a relatively short period of time, China has amassed more than $1.6 trillion in foreign-exchange reserves, the largest such reservoir in history. While this cushions China from the vicissitudes of ever volatile financial markets, much of it is invested in low-yielding U.S. Treasury securities. So authorities earmarked $200 billion of this pool for a new sovereign wealth fund, the China Investment Corp. (CIC), which Lou now runs. The goal: generate higher returns through advanced asset-management techniques. <br /><br />Lou must assemble a first-rate management team as well as develop an investment discipline aligned with China's longer-term return objectives. As if that were not enough, he has also been thrust into the heart of an intense geopolitical debate over the role governments should play in shaping cross-border investment. If successful, the CIC could receive billions more of investable capital—which could quickly turn Lou into one of the most powerful fund managers on the planet.<br /><br />Roach is an economist and the chairman of Morgan Stanley Asia <br /><br /><br /><br />Dalai Lama也上了，没办法，当年本拉登那也是榜上有名！<br />有很多互联网的公司创始人都上了，Digg.com的Jay Adelson，Amazon.com的Jeff Bezos......<br />“很好，很强大”是没上，，看来《time》还是评判标准是有点问题的。。<br />就搞不懂，2008年都还到一半，就要评了，，好像美国现在也是2008年啊。。<img src="/images/smiles/icon_biggrin.gif"/><br /><br />我把收集的Leaders & Revolutionaries放到附件里，，想看下可以去下，有图片和大概500字左右的评价(en的)！<br />其他部分可以MSN：yate7571@hotmail.com我，，我会尽快整理好！
          <br/>
          <span style="color:red;">
            <a href="http://yate.javaeye.com/blog/188828#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</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, 02 May 2008 13:37:48 +0800</pubDate>
        <link>http://yate.javaeye.com/blog/188828</link>
        <guid>http://yate.javaeye.com/blog/188828</guid>
      </item>
      <item>
        <title>我的简历，希望指出问题！期待！</title>
        <author>yate</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://yate.javaeye.com">yate</a>&nbsp;
          链接：<a href="http://yate.javaeye.com/blog/188774" style="color:red;">http://yate.javaeye.com/blog/188774</a>&nbsp;
          发表时间: 2008年05月02日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          简          历<br /> <br /> <br /> <br />基 本 信 息    <br />姓  名：  胡勇 性  别：  男  <br />出生日期： 1987年01月15日 居 住 地： 长沙市  <br />工作年限： 在读学生  户  口：  湖南  <br />地  址：  湖南长沙                       政治身份：        中共党员 <br />邮  编：  410600                      <br />电子邮件： yate7571@hotmail.com <br />家庭电话： 07328384186 <br />移动电话： 13117523096 <br />个人主页： http://yate.javaeye.com/ <br /> <br />自 我 评 价    <br />  <br />1，较强的团队合作精神,有强的责任心 <br />2，具有好的创新精神，学习能力强，独立思考能力较强 <br />3，热爱软件开发，能够吃苦耐劳 <br />4，十分爱好体育锻炼<br />5，善于与人交流沟通 <br />6，流畅的阅读英文文档 <br />7，数学基础好，数据结构比较熟悉 <br />8，能够用SSH,Ajax(GWT)开发项目 <br />9，对rose建模掌握较好 <br />10，对mysql，oracle数据库较为熟悉 <br /> <br />求 职 意 向    <br />  <br />工作性质： 全/兼职  <br />希望行业： 计算机软件  <br />目标地点： 北京市，广东省，上海市，深圳市，杭州市  <br />期望工资： 面议 /月 <br />目标职能： 计算机软件  <br /> <br />工 作 经 验    <br />2007/09--至今：湖南科技大学网格实验室 <br />所属行业： 计算机软件  <br />知识网格实验室  软件工程师  <br />目前在开发一个WebService的项目，主要是搜索引擎的设计，实现,WSDL,WSIL的搜索等，以及门户网站的开发(Spring+hibernate+Struts+GWT) <br />工作业绩： 1，用Rose建模 <br />2，开发搜索引擎客户端等 <br />3，设计搜索引擎，设计过滤器等 <br />4，部署和测试 <br />5，SSH开发门户网站和后台管理系统 <br /> <br /> <br />项 目 经 验    <br />2008/03--至今：WebService <br />软件环境： Jsp+JavaBean+SSH+Xfire+GWT <br />硬件环境： Windows Server2003/Windows XP/Linux <br />开发工具： Myeclipse5.5+Oracle9i+Jboss4.0+GWTDesinger6.0 <br />项目描述： 1，实现自己的Webservice并提供接口 <br />2，搜索Internet网上的公共WS <br />责任描述： 1，用rose建模 <br />2, 设计搜索引擎(java)，并设计过滤器，并实现 <br />3，设计持久层和数据层并测试 <br />4，用GWT实现RPC <br />5，解析WSDL，WSIL，Disco等 <br />6，SSH开发WebService门户网站(http://www.hnustsc.3322.org) <br /><br />--------------------------------------------------------------------------------<br /> <br />2008/02--2008/03：教学管理系统 <br />软件环境： SSH+Ajax+tomcat5.5/Jboss4.0+Oracle9i/Mysql <br />硬件环境： WindowXP/Window Server2003 <br />开发工具： MyEclipse5.5 AptanaStudio <br />项目描述： 采用了SSH框架，MVC模式，数据层用Hibernate持久化，并用DAO模式对数据操作，数据库为Oracle9i/Mysql5.0,用Ajax增加了用户体验，并实现了国际化，用rose建模 <br />责任描述： 1，建模(IBM Rational rose) <br />2, 系统分层设计(MVC),定义好接口 <br />3，实现各个模块 <br />4，测试数据层 <br />5，部署 <br />6，组成文档的编写 <br /> <br /> <br />教 育 经 历    <br />2005/09--至今 湖南科技大学  计算机科学与技术   本科  <br /> <br /> <br />所 获 奖 励    <br />2006/09 2005-2006年度校级优秀学生干部  校级 <br /><br />--------------------------------------------------------------------------------<br /> <br />2006/05 校级“五四”青年干部  校级 <br /> <br /> <br />社 会 实 践    <br />2008/03--至今 WebServices  实践  <br />在湖南科技大学知识网格实验室做WebService项目 <br />2005/09--至今 中国百胜集团  实践  <br />从事服务业方面的工作，很好的锻炼的自己毅力和吃苦耐劳的精神！对工作有热情，充满活力！ <br />2005/09--2006/ 09      团总支书记  职务  <br />主要分管学生工作和计算机技术和网络技术方面的管理！ <br /> <br /> <br />证 书    <br />2007/12 大学英语四级    <br /> <br /> <br />语 言 能 力    <br />英语  良好
          <br/>
          <span style="color:red;">
            <a href="http://yate.javaeye.com/blog/188774#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</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, 02 May 2008 10:58:49 +0800</pubDate>
        <link>http://yate.javaeye.com/blog/188774</link>
        <guid>http://yate.javaeye.com/blog/188774</guid>
      </item>
      <item>
        <title>关于延迟加载Bean的问题</title>
        <author>yate</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://yate.javaeye.com">yate</a>&nbsp;
          链接：<a href="http://yate.javaeye.com/blog/188768" style="color:red;">http://yate.javaeye.com/blog/188768</a>&nbsp;
          发表时间: 2008年05月02日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          对这个延迟加载Bean不是太懂，以前在做一个Hibernate项目的时候(没用到Spring),更新数据的时候老是提示无法打开session,,应该是查询的时候已经关闭session了，再去更新（插入）就会失败，，当时一个朋友说用到spring的延迟加载策略比较好，现在贴下这个问题，当时好像那个更新的块是单独搞的，先查询，再修改然后再关闭session，但这就产生了一个问题，自己的设计不一致（比如说Delete，Insert，Add都是作为单独的业务逻辑块分离出来了，用到了一个HibernateUtil（HibernateFactory）管理，功能算是解决了，但很垃圾。。<br />请问下谁可以提供下延迟加载Bean的资料？
          <br/>
          <span style="color:red;">
            <a href="http://yate.javaeye.com/blog/188768#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/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</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, 02 May 2008 10:20:05 +0800</pubDate>
        <link>http://yate.javaeye.com/blog/188768</link>
        <guid>http://yate.javaeye.com/blog/188768</guid>
      </item>
      <item>
        <title>夏天来了</title>
        <author>yate</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://yate.javaeye.com">yate</a>&nbsp;
          链接：<a href="http://yate.javaeye.com/blog/188732" style="color:red;">http://yate.javaeye.com/blog/188732</a>&nbsp;
          发表时间: 2008年05月01日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          夏天应该算是我的季节，难怪我皮肤黝黑的，可以去游泳了，今天特意把装备换了，同时得解决下中午睡觉问题。。不过接下来的几个月一点也不轻松的，太多的事要做，一件一件的来，保持好心态，持之以恒，做到有效率，有目的就OK了！！<img src="/images/smiles/icon_biggrin.gif"/>
          <br/>
          <span style="color:red;">
            <a href="http://yate.javaeye.com/blog/188732#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><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, 01 May 2008 22:48:37 +0800</pubDate>
        <link>http://yate.javaeye.com/blog/188732</link>
        <guid>http://yate.javaeye.com/blog/188732</guid>
      </item>
      <item>
        <title>Bean的初始化和销毁方法</title>
        <author>yate</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://yate.javaeye.com">yate</a>&nbsp;
          链接：<a href="http://yate.javaeye.com/blog/188731" style="color:red;">http://yate.javaeye.com/blog/188731</a>&nbsp;
          发表时间: 2008年05月01日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          1，初始化方法是在对象创建后并完成注入工作后执行，所以可以对对象的创建和配置文件的正确进行测试；<br />2，销毁方法：释放资源<br /><br />在文件中增加<br />init-method="initialize"<br />destory-method="cleanup"<br /><br />当然在操作的bean中对应需要由initialize()方法和cleanup()方法<br /><br />3，还可以使用spring所定义的接口：<br />    org.springframework.beans.factory.InitializingBean()接口（afterPropertiesSet()方法）<br />    org.springframework.beans.factory.DisposableBean()接口<br />（destory()方法）<br />    但是不推荐这样做，会产生耦合，违反设计初衷。<br /><br />感觉这个还是比较简单，对自己代码唯一的保证是测试，单元测试，整合测试，系统测试！
          <br/>
          <span style="color:red;">
            <a href="http://yate.javaeye.com/blog/188731#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/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</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, 01 May 2008 22:44:59 +0800</pubDate>
        <link>http://yate.javaeye.com/blog/188731</link>
        <guid>http://yate.javaeye.com/blog/188731</guid>
      </item>
      <item>
        <title>Bean的作用域介绍(Singleton与prototype)</title>
        <author>yate</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://yate.javaeye.com">yate</a>&nbsp;
          链接：<a href="http://yate.javaeye.com/blog/188555" style="color:red;">http://yate.javaeye.com/blog/188555</a>&nbsp;
          发表时间: 2008年04月30日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          Spring Bean作用域介绍：<br /><br />singleton：SpringIoc容器只会创建该Bean的唯一实例，所有的请求和引用都只使用这个实例<br />Property:  每次请求都创建一个实例<br />request:    在一次Http请求中，容器会返回该Bean的同一个实例，而对于不同的用户请求，会返回不同的实例。需要注意的是，该作用域仅在基于Web的Spring ApplicationContext情形下有效，以下的session和global Session也是如此<br />session：同上，唯一的区别是请求的作用域变为了session<br />global session：全局的HttpSession中，容器会返回该bean的同一个实例，典型为在是使用portlet context的时候有效（这个概念本人也不懂）<br /><br />注意：如果要用到request，session，global session时需要配置<br /><br />servlet2.4及以上：<br />在web.xml中添加：<br />&lt;listener><br />    &lt;listener-class>org.springframework.web.context.scope.RequestContextListener /><br />&lt;/listener><br /><br />servlet2.4以下：<br />需要配置一个过滤器<br />&lt;filter><br />    &lt;filter-name>XXXX&lt;/filter-name><br />    &lt;filter-class>org.springframework.web.filter.RequestContextFilter&lt;/filter-class><br />&lt;filter-mapping><br />    &lt;filter-name>XXXX&lt;/filter-name><br />    &lt;url-pattern>/*&lt;/url-pattern><br />&lt;/filter-mapping><br /><br />另外，从2.0开始，可以自己定义作用域，但需要实现scope，并重写get和remove方法<br /><br />特别要引起注意的是：<br />   一般情况下前面两种作用域是够用的，但如果有这样一种情况：singleton类型的bean引用一个prototype的bean时会出现问题，因为singleton只初始化一次，但prototype每请求一次都会有一个新的对象，但prototype类型的bean是singleton类型bean的一个属性，理所当然不可能有新prototpye的bean产生，与我们的要求不符<br /><br />解决方法：<br />1.放弃Ioc，这与设计初衷不符，并代码间会有耦合<br />2，Lookup方法注入，推荐<br /><br />但在用Lookup方法注入时也需要注意一点：需要在引用的Bean中定一个一个抽象地返回被引用对象的方法<br /><br />package com.huyong.lookup;<br /><br />import java.util.Calendar;<br /><br />/**<br /> * @author HuYong Email:yate7571@hotmail.com<br /> */<br />public class CurrentTime {<br />	private Calendar now = Calendar.getInstance();<br /><br />	public void printCurrentTime() {<br />		System.out.println("Current Time:" + now.getTime());<br />	}<br /><br />}<br /><br /><br />package com.huyong.lookup;<br /><br />/**<br /> * @author HuYong Email:yate7571@hotmail.com<br /> */<br />public abstract class LookupBean {<br />	private CurrentTime currentTime;<br /><br />	public CurrentTime getCurrentTime() {<br />		return currentTime;<br />	}<br /><br />	public void setCurrentTime(CurrentTime currentTime) {<br />		this.currentTime = currentTime;<br /><br />	}<br />	public abstract CurrentTime createCurrentTime();<br /><br />}<br /><br />&lt;?xml version="1.0" encoding="UTF-8"?><br />&lt;beans xmlns="http://www.springframework.org/schema/beans"<br />	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"<br />	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd"><br /><br />	&lt;bean id="currentTime" class="com.huyong.lookup.CurrentTime"<br />		scope="prototype"><br />	&lt;/bean><br />	&lt;bean id="lookupBean" class="com.huyong.lookup.LookupBean"<br />		scope="singleton"><br />		&lt;lookup-method name="createCurrentTime" bean="currentTime" /><br />		&lt;property name="currentTime" ref="currentTime">&lt;/property><br />	&lt;/bean><br /><br />&lt;/beans><br /><br /><br />Main Test：<br />package com.huyong.lookup;<br /><br />import org.springframework.beans.factory.BeanFactory;<br />import org.springframework.beans.factory.xml.XmlBeanFactory;<br />import org.springframework.core.io.ClassPathResource;<br /><br />/**<br /> * @author HuYong Email:yate7571@hotmail.com<br /> */<br />public class LookupMain {<br /><br />	/**<br />	 * @param args<br />	 * @throws Exception<br />	 */<br />	public static void main(String[] args) throws Exception {<br />		ClassPathResource resource = new ClassPathResource(<br />				"applicationContext.xml");<br />		BeanFactory factory = new XmlBeanFactory(resource);<br /><br />		LookupBean lookupBean = (LookupBean) factory.getBean("lookupBean");<br />		System.out.println("----------first time---------");<br />		System.out.println("getCurrentTime:");<br />		lookupBean.getCurrentTime().printCurrentTime();<br />		System.out.println("createCurrentTime:");<br />		lookupBean.createCurrentTime().printCurrentTime();<br /><br />		Thread.sleep(12345);<br /><br />		System.out.println("---------second time---------");<br />		System.out.println("getCurrentTime:");<br />		LookupBean lookupBean02 = (LookupBean) factory.getBean("lookupBean");<br />		lookupBean02.getCurrentTime().printCurrentTime();<br />		System.out.println("createCurrentTime:");<br />		lookupBean02.createCurrentTime().printCurrentTime();<br /><br />	}<br /><br />}<br /><br /><br />感觉Spring的东西比较杂，学好spring一定要明白反射和代理是怎么回事！<br />渐渐的也挺会到了Spring的好处！<br />简单就是美！！
          <br/>
          <span style="color:red;">
            <a href="http://yate.javaeye.com/blog/188555#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><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>Wed, 30 Apr 2008 20:52:53 +0800</pubDate>
        <link>http://yate.javaeye.com/blog/188555</link>
        <guid>http://yate.javaeye.com/blog/188555</guid>
      </item>
      <item>
        <title>开始我的技术Blog</title>
        <author>yate</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://yate.javaeye.com">yate</a>&nbsp;
          链接：<a href="http://yate.javaeye.com/blog/188166" style="color:red;">http://yate.javaeye.com/blog/188166</a>&nbsp;
          发表时间: 2008年04月29日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          这段时间得把所有的基础复习下，特别是重点看下Spring和GWT，早就想在javaeye写点我的学习笔记了，，以后会经常把所学的贴上去，欢迎大家给我提意见和建议！<img src="/images/smiles/icon_smile.gif"/>
          <br/>
          <span style="color:red;">
            <a href="http://yate.javaeye.com/blog/188166#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><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><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Tue, 29 Apr 2008 19:50:34 +0800</pubDate>
        <link>http://yate.javaeye.com/blog/188166</link>
        <guid>http://yate.javaeye.com/blog/188166</guid>
      </item>
      <item>
        <title>使用构造方法创建Bean实例</title>
        <author>yate</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://yate.javaeye.com">yate</a>&nbsp;
          链接：<a href="http://yate.javaeye.com/blog/188164" style="color:red;">http://yate.javaeye.com/blog/188164</a>&nbsp;
          发表时间: 2008年04月29日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          1，create a Message Interface:<br /><br />package com.huyong.beans;<br /><br />public interface Message {<br />	public String showMessage();<br /><br />}<br /><br /><br />2,create another Person Interface:<br /><br />package com.huyong.beans;<br /><br />public interface Person {<br />	public void useMessage();<br /><br />}<br /><br /><br />3,implement the Message's interface and the Person's interface<br /><br />package com.huyong.beans;<br /><br />public class MyPerson implements Person {<br />	private Message message;<br /><br />	public void useMessage() {<br />		System.out.println(message.showMessage());<br /><br />	}<br /><br />	/**<br />	 * @return the message<br />	 */<br />	public Message getMessage() {<br />		return message;<br />	}<br /><br />	/**<br />	 * @param message<br />	 *            the message to set<br />	 */<br />	public void setMessage(Message message) {<br />		this.message = message;<br />	}<br /><br />}<br /><br /><br />package com.huyong.beans;<br /><br />public class MyMessage implements Message {<br /><br />	public String showMessage() {<br />		return "these are my messages!";<br />	}<br /><br />}<br /><br /><br />4,the Main function:<br /><br />package com.huyong.beans;<br /><br />import org.springframework.beans.factory.BeanFactory;<br />import org.springframework.beans.factory.xml.XmlBeanFactory;<br />import org.springframework.core.io.ClassPathResource;<br /><br />public class TestMain {<br /><br />	/**<br />	 * @param args<br />	 */<br />	public static void main(String[] args) {<br />		ClassPathResource resource = new ClassPathResource(<br />				"applicationContext.xml");<br />		BeanFactory factory = new XmlBeanFactory(resource);<br />		Person person = (Person) factory.getBean("myperson");<br />		person.useMessage();<br /><br />	}<br /><br />}<br /><br /><br /><br />5,config applicationContext.xml:<br /><br />&lt;?xml version="1.0" encoding=