<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
  <channel>
    <title>stamen</title>
    <description>某天某月的某一天 我住进了自己的房子 老婆孩子热炕头--Wonderful dream...</description>
    <link>http://stamen.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>5种DAO查询方法的签名方式，哪个更好？</title>
        <author>stamen</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://stamen.javaeye.com">stamen</a>&nbsp;
                    链接：<a href="http://stamen.javaeye.com/blog/152830" style="color:red;">http://stamen.javaeye.com/blog/152830</a>&nbsp;
          发表时间: 2008年01月03日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          DAO类中查询方法的签名多种多样，大家都使用什么签名方法呢？拿出来讨论一下吧。&nbsp;&nbsp; <br /> <br />&nbsp;&nbsp;&nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;DAO层除了CRUD的数据操作外，另一个重要的操作就是根据查询条件执行数据查询，不同的ORM框架都允许用户动态绑定参数确定查询条件。查询条件项的数目往往是不固定的，如既可能要求以userName为条件查询User，也可能要求以userName+status等组合条件查询User。条件项数目的不定性给查询接口方法的设计造成为一定的困难，实体DAO定义带参的查询方法时，一般有5种方式，下面分别对这些方法进行介绍。<br /><br /><strong>方式1：每一个条件项参数对应一个入参</strong><br /><br />&nbsp;&nbsp;&nbsp;&nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;查询方法中为每一个查询条件项定义一个对应的入参，如：<br /><pre name="code" class="java">List  findOrder(String hql,Date startTime,Date endTime,int deptId)</pre><br /><br />&nbsp;&nbsp;&nbsp;&nbsp; 这种方法签名含义清晰，可读性强，内部的逻辑处理简单，但接口稳定性差。<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 假如这个findOrder()方法需要添加一个userName的条件，有两种重构的方式：第一，调整方法的签名，新增一个String userName入参，这种重构被认为是不健康的重构，因为它违反软件设计中经典的“开-闭原则”，此外如果条件项个数很多，方法签名将显得过于拖沓；第二，在DAO类中新增一个重载查询方法，如果查询条件项的组合数过多，DAO类的方法数目将直线上升，整个实体DAO类将显得臃肿笨重。<br /><br /><strong>方式2：使用数组传递条件项参数</strong><br /><br />&nbsp;&nbsp;&nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;通过数组的方式传递查询条件项参数，由于参数类型的不一致性，要求数组类型采用Object[]：<br /><pre name="code" class="java">List  findOrder(String hql,Object[] params)</pre><br /><br />&nbsp;&nbsp;&nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;这种方法接口可以应付查询条件项参数组合的多样性并保持接口的稳定性，开发者必须在方法内部从数组中获取参数再传递给查询引擎。缺点是方法的可读性不强，调用者往往需要通过查看接口对应的Javadoc才能正确使用。此外，在JDK 5.0以下的版本中，因为没有自动拆/解包的语法特性，调用前必须对基本类型的参数使用封装类封装，有时在方法内部还需要进行相反的过程，在使用上较为不便。不过由于Spring为支持的ORM框架都提供了类似的查询接口（如HibernateTemplate#find(String queryString, Object[] values)），所以DAO方法内部的处理相对还是比较简单的。<br /><br />&nbsp;&nbsp;&nbsp; <strong>方式3：使用JDK 5.0的不定参数</strong><br /><br />&nbsp;&nbsp;&nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;如果在JDK 5.0中，则可以采用不定参数进行方法签名，这种方式在逻辑上和方式2并无多大的区别：<br /><pre name="code" class="java">List  findOrder(String hql,Object... params)</pre><br /><br />&nbsp;&nbsp; <strong>方式4：将查询条件项参数封装成对象</strong><br /><br />&nbsp;&nbsp;&nbsp;&nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;为了提高方法1中方法签名简洁性，增强方法2、3中方法签名的可读性，方式4提出将查询条件项参数封装成一个对象的思路，查询方法使用查询条件对象传递查询条件：<br /><br /><pre name="code" class="java">List&lt;Order> findOrder(String hql,OrderQueryParam param)</pre><br /><br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;OrderQueryParam查询条件对象封装了hql查询语句可能会用到的条件项参数，在查询方法内部，开发者必须判断查询条件对象的属性并正确绑定条件项参数。由于需要为条件项参数定义一个类，因此会造成类数目的膨胀，有时甚至一个实体DAO需要对应多个查询条件参数类。另外，当需要添加一个新的条件项参数时，条件封装类还需要进行相应调整。<br /><br />&nbsp; <strong>方式5：使用Map传递条件项参数</strong><br /><br />&nbsp;&nbsp;&nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;另一种被广泛使用的方法是采用Map传递条件项参数，键为参数名，值为参数值：<br /><pre name="code" class="java">List&lt;Order> findOrder(String hql,Map params)</pre><br />&nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;使用这种方式，接口方法签名可以在条件项发生变化的情况下保持稳定，同时通过键指定条件项参数名在一定程度上解决了接口的健壮性（当调用者指定错误参数名时容易得到错误报警）。但和方法2、3一样调用者必须通过接口Javadoc才能明白不同条件项要以什么名称进行设置。<br /><br /><span style="color: red">注：以上5个查询方法签名的总结摘自于《精通Spring 2.x--企业应用开发详解》</span>
          <br/><br/>
          <span style="color:red;">
            <a href="http://stamen.javaeye.com/blog/152830#comments" style="color:red;">已有 <strong>22</strong> 人发表留言，猛击-&gt;&gt;<strong>这里</strong>&lt;&lt;-参与讨论</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;">Windows7在微软WinHEC 2008上揭开神秘面纱</span></a></li><li><a href='/adverts/138' 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, 03 Jan 2008 15:23:24 +0800</pubDate>
        <link>http://stamen.javaeye.com/blog/152830</link>
        <guid>http://stamen.javaeye.com/blog/152830</guid>
      </item>
          <item>
        <title>直接使用Junit测试Spring应用的4点不足</title>
        <author>stamen</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://stamen.javaeye.com">stamen</a>&nbsp;
                    链接：<a href="http://stamen.javaeye.com/blog/151981" style="color:red;">http://stamen.javaeye.com/blog/151981</a>&nbsp;
          发表时间: 2007年12月30日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          在开发基于Spring的应用时，如果你还直接使用Junit进行单元测试，那你就错过了Spring为我们所提供的饕餮大餐了。使用Junit直接进行单元测试有以下四大不足：<br /><br />&nbsp;&nbsp; 1）<strong>导致多次Spring容器初始化问题</strong><br /><br />&nbsp;&nbsp; 根据JUnit测试方法的调用流程，每执行一个测试方法都会创建一个测试用例的实例并调用setUp()方法。由于一般情况下，我们在setUp()方法中初始化Spring容器，这意味着如果测试用例有多少个测试方法，Spring容器就会被重复初始化多次。虽然初始化Spring容器的速度并不会太慢，但由于可能会在Spring容器初始化时执行加载Hibernate映射文件等耗时的操作，如果每执行一个测试方法都必须重复初始化Spring容器，则对测试性能的影响是不容忽视的；<br /><br />&nbsp;&nbsp;&nbsp; <span style="color: green">－－>使用Spring测试套件，Spring容器只会初始化一次！</span><br /><br />&nbsp;&nbsp; 2）<strong>需要使用硬编码方式手工获取Bean</strong><br /><br />&nbsp;&nbsp;&nbsp; 在测试用例类中我们需要通过ctx.getBean()方法从Spirng容器中获取需要测试的目标Bean，并且还要进行强制类型转换的造型操作。这种乏味的操作迷漫在测试用例的代码中，让人觉得烦琐不堪；<br /><br />&nbsp;&nbsp;&nbsp; <span style="color: green">－－>使用Spring测试套件，测试用例类中的属性会被自动填充Spring容器的对应Bean<br />，无须在手工设置Bean！</span><br />&nbsp;&nbsp; <br />&nbsp;&nbsp; 3）<strong>数据库现场容易遭受破坏</strong><br /><br />&nbsp;&nbsp;&nbsp; 测试方法对数据库的更改操作会持久化到数据库中。虽然是针对开发数据库进行操作，但如果数据操作的影响是持久的，可能会影响到后面的测试行为。举个例子，用户在测试方法中插入一条ID为1的User记录，第一次运行不会有问题，第二次运行时，就会因为主键冲突而导致测试用例失败。所以应该既能够完成功能逻辑检查，又能够在测试完成后恢复现场，不会留下“后遗症”；<br /><br />&nbsp;&nbsp;&nbsp; <span style="color: green">－－>使用Spring测试套件，Spring会在你验证后，自动回滚对数据库的操作，保证数据库的现场不被破坏，因此重复测试不会发生问题！</span><br /><br />&nbsp;&nbsp; 4）<strong>不方便对数据操作正确性进行检查</strong><br />&nbsp;&nbsp;&nbsp; <br />&nbsp;&nbsp;&nbsp; 假如我们向登录日志表插入了一条成功登录日志，可是我们却没有对t_login_log表中是否确实添加了一条记录进行检查。一般情况下，我们可能是打开数据库，肉眼观察是否插入了相应的记录，但这严重违背了自动测试的原则。试想在测试包括成千上万个数据操作行为的程序时，如何用肉眼进行检查？<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: green">－－>只要你继承Spring的测试套件的用例类，你就可以通过jdbcTemplate在同一事务中访问数据库，查询数据的变化，验证操作的正确性！</span><br /><br />&nbsp;&nbsp; <br />&nbsp;&nbsp;&nbsp; Spring提供了一套扩展于Junit测试用例的测试套件，使用这套测试套件完全解决了以上四个问题，让我们测试Spring的应用更加方便。现在我的项目中已经完成摒弃Junit，而采用Spring的测试套件，确实带来了很大的便利。严重推荐Springer使用这个测试套件。这个测试套件主要由org.springframework.test包下的若干类组成，使用简单快捷，方便上手。<br /><br />&nbsp;&nbsp; <span style="color: red"> 注：以上四个不足的总结摘自《精通Spring 2.x --企业应用开发详解》</span>
          <br/><br/>
          <span style="color:red;">
            <a href="http://stamen.javaeye.com/blog/151981#comments" style="color:red;">已有 <strong>14</strong> 人发表留言，猛击-&gt;&gt;<strong>这里</strong>&lt;&lt;-参与讨论</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/138' target='_blank'><span style="color:red;font-weight:bold;">加入阿里巴巴，发展潜力无限</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">Windows7在微软WinHEC 2008上揭开神秘面纱</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sun, 30 Dec 2007 17:43:57 +0800</pubDate>
        <link>http://stamen.javaeye.com/blog/151981</link>
        <guid>http://stamen.javaeye.com/blog/151981</guid>
      </item>
          <item>
        <title>谈谈Spring 2.x中简化配置的问题</title>
        <author>stamen</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://stamen.javaeye.com">stamen</a>&nbsp;
                    链接：<a href="http://stamen.javaeye.com/blog/148519" style="color:red;">http://stamen.javaeye.com/blog/148519</a>&nbsp;
          发表时间: 2007年12月15日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          谈谈Spring 2.x中简化配置的问题<br /><br />Spring 2.x在配置文件的简化的方面做了很多工作，原来1.x中比较麻烦的配置都已经拥有了比较完美的解决方案。最近刚看完《精通Spring 2.x --企业应用开发精解》的书，结合自己的经验整理一下简化配置的内容。<br /><br /><strong>一、关于集合的配置</strong><br /><em>1.List</em><br />>1.x版本的<br /><pre name="code" class="java">
&lt;bean id="parentBoss" abstract="true"class="com.baobaotao.attr.Boss"> &lt;--父&lt;bean>
	&lt;property name="favorites">
		&lt;set>
			&lt;value>看报&lt;/value>
			&lt;value>赛车&lt;/value>
			&lt;value>高尔夫&lt;/value>
		&lt;/set>
	&lt;/property>
&lt;/bean>
</pre><br /><br />>2.x版本的<br /><pre name="code" class="java">&lt;util:list id="favoriteList1" list-class="java.util.LinkedList">
	&lt;value>看报&lt;/value>
	&lt;value>赛车&lt;/value>
	&lt;value>高尔夫&lt;/value>
&lt;/util:list></pre><br /><br /><em>2.Set</em><br />> 1.x<br /><pre name="code" class="java">&lt;bean id="boss1" class="com.baobaotao.attr.Boss">
	&lt;property name="favorites">
	   &lt;set> 
	      &lt;value>看报&lt;/value>
	      &lt;value>赛车&lt;/value>
	      &lt;value>高尔夫&lt;/value>
	   &lt;/set>
	&lt;/property>
&lt;/bean></pre><br />> 2.x<br /><pre name="code" class="java">    
   &lt;util:set id="favoriteSet1">
	   &lt;value>看报&lt;/value>
	   &lt;value>赛车&lt;/value>
	    &lt;value>高尔夫&lt;/value>
   &lt;/util:set>
</pre><br /><em>&nbsp;&nbsp; 3.Map</em><br />> 1.x<br /><pre name="code" class="java">
&lt;bean id="boss1" class="com.baobaotao.attr.Boss">
    &lt;property name="jobs">
	&lt;map>
	      &lt;!--Map第一个元素-->
               &lt;entry> 
	          &lt;key>&lt;value>AM&lt;/value>&lt;/key>
	          &lt;value>会见客户&lt;/value>
	       &lt;/entry>
	      &lt;!--Map第二个元素-->
               &lt;entry> 
	          &lt;key>&lt;value>PM&lt;/value>&lt;/key>
	          &lt;value>公司内部会议&lt;/value>
	      &lt;/entry>		      
	&lt;/map>
    &lt;/property>
&lt;/bean></pre><br />> 2.x<br /><pre name="code" class="java">
&lt;util:map id="emails1">
	&lt;entry key="AM" value="会见客户" />
	&lt;entry key="PM" value="公司内部会议" />
&lt;/util:map>
</pre><br /><br /><em>&nbsp;&nbsp; 4. Properties</em><br /><br />> 1.x<br /><pre name="code" class="java">
&lt;bean id="boss1" class="com.baobaotao.attr.Boss">
	&lt;property name="mails">
	    &lt;props>
	       &lt;prop key="jobMail">john-office@baobaotao.com&lt;/prop>
	       &lt;prop key="lifeMail">john-life@baobaotao.com&lt;/prop>
	    &lt;/props>
	&lt;/property>
&lt;/bean>
</pre><br /><br />> 2.x<br /><pre name="code" class="java">
  &lt;util:properties id="emailProps1" location="classpath:com/baobaotao/fb/mails.properties"/>
</pre><br />可以在一个属性文件中直接配置属性，这比较符合一般的项目习惯。<br /><br /><strong>二、	关于事务配置</strong><br /><br /><br />1.1.x<br /><pre name="code" class="java">
  &lt;bean id="bbtForum" 
	class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
	&lt;property name="transactionManager" ref="txManager" /> 
	&lt;property name="target" ref="bbtForumTarget"/>
	&lt;property name="transactionAttributes"> 
		&lt;props>
			&lt;prop key="get*">PROPAGATION_REQUIRED,readOnly&lt;/prop> 
			&lt;prop key="*">PROPAGATION_REQUIRED&lt;/prop> 
		&lt;/props>
	&lt;/property>
  &lt;/bean>
</pre><br /><br />2.2.x<br /><br />有两种新方法<br />a)使用@Transactional注解<br />在需要的服务类或服务方法处直接打上@Transactional注解，然后在Spring配置文件中启用注解事务驱动就可以了：<br /><br /><pre name="code" class="java">
@Transactional 
public class BbtForumImpl implements BbtForum {
	@Transactional(readOnly=true) 
	public Forum getForum(int forumId) {
		return forumDao.getForum(forumId);
	}
       。。。。
}
</pre><br />在Spring配置文件中相应添加上：<br /><pre name="code" class="java">
&lt;bean id="txManager"
		class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		&lt;property name="dataSource" ref="dataSource" />
&lt;/bean>
&lt;tx:annotation-driven transaction-manager="txManager"/>
</pre><br />这样就OK了，简单吧：）<br /><br />b)使用aop/tx<br /><br />如果你的Service服务类都很规范，我觉得使用aop/tx更方面，因为不用到处打注解，在一处集中配置就OK了，可谓运筹帷幄之中，决胜于千里之外：）<br /> <pre name="code" class="java"> 
     &lt;aop:config> 
	  &lt;aop:pointcut id="serviceMethod" 
		      expression="execution(* com.baobaotao.service.*Forum.*(..))" />
	  &lt;aop:advisor pointcut-ref="serviceMethod" advice-ref="txAdvice" /> 
      &lt;/aop:config>
     &lt;tx:advice id="txAdvice" transaction-manager="txManager"> 
        &lt;tx:attributes> 
            &lt;tx:method name="get*" read-only="false"/>
            &lt;tx:method name="add*" rollback-for="Exception" />
            &lt;tx:method name="update*"/>         
        &lt;/tx:attributes>
    &lt;/tx:advice>
  </pre><br /> <br /><strong>三、关于AOP配置</strong><br /><br />&nbsp; 原来1.x的AOP太麻烦了，提都不想提，直接说一下2.x的AOP。<br />Spring 2.x使用@AspectJ来描述切面，由于@AspectJ的语法描述能力超强，因此在Spring 2.x中使用AOP真的非常方便。<br /><br />&nbsp;&nbsp;&nbsp; 在使用@AspectJ之前，首先你得保证你所使用的JDK的版本是5.0及以上版本，否则无法使用注解技术。<br />Spring在处理@Aspect注解表达式时，需要使用位于spring/lib/asm下asm关联类库，将该类库的三个类包加入到类路径中：asm-2.2.2.jar、asm-commons-2.2.2.jar和asm-util-2.2.2.jar。我们在第一章中了解了asm类库的用途，它是轻量级的字节码处理框架，因为Java的反射机制无法获取入参名，Spring就利用asm处理@AspectJ中所描述的方法入参名。<br /><br />&nbsp;&nbsp;&nbsp; 此外，Spring采用AspectJ提供的@AspectJ注解类库及相应的解析类库，它位于spring/lib/aspectj目录下，将目录下的aspectjrt.jar和aspectjweaver.jar类包加入类路径中。<br />在做好上节中所提到的前置工作后，我们就可以开始编写一个基于@AspectJ的切面了，首先来看一个简单的例子，以便对@AspectJ有一个切身的认识。<br /><br />&nbsp;&nbsp; @AspectJ采用不同的方式对AOP进行描述， 我们使用NaiveWaiter的例子来说明，这是一个希望引入切面的目标类：<br /><pre name="code" class="java">
package com.baobaotao;
public class NaiveWaiter implements Waiter {
	public void greetTo(String clientName) {
		System.out.println("NaiveWaiter:greet to "+clientName+"...");
	}
	public void serveTo(String clientName){
		System.out.println("NaiveWaiter:serving "+clientName+"...");
	}	
}
</pre><br /><br />下面使用@AspectJ来定义一下切面：<br /><pre name="code" class="java">
package com.baobaotao.aspectj.aspectj;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
//通过该注解将PreGreetingAspect标识为一个切面
@Aspect 
public class PreGreetingAspect{
	@Before("execution(* greetTo(..))") //&lt;---定义切点和增强类型
	public void beforeGreeting(){ //&lt;----增强的横切逻辑
		System.out.println("How are you");
	}
}
</pre><br /><br />然后启动@AspectJ的注解切面驱动就可以了！<br /><pre name="code" class="java">
&lt;?xml version="1.0" encoding="UTF-8" ?>
&lt;beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:aop="http://www.springframework.org/schema/aop" 
	xsi:schemaLocation="http://www.springframework.org/schema/beans
<a href="http://www.springframework.org/schema/beans/spring-beans-2.0.xsd" target="_blank">http://www.springframework.org/schema/beans/spring-beans-2.0.xsd</a>
                        http://www.springframework.org/schema/aop 
<a href="http://www.springframework.org/schema/aop/spring-aop-2.0.xsd" target="_blank">http://www.springframework.org/schema/aop/spring-aop-2.0.xsd</a>">
	&lt;!--基于@AspectJ切面的驱动器-->
        &lt;aop:aspectj-autoproxy /> 
	&lt;bean id="waiter" class="com.baobaotao.NaiveWaiter" />
	&lt;bean class="com.baobaotao.aspectj.example.PreGreetingAspect" />
&lt;/beans>
</pre><br /><br /><strong>四、关于Spring 2.1添加的新功能</strong><br /><br />1.原来引入一个外面属性配置文件需要使用以下的方式：<br /><pre name="code" class="java">
&lt;bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
	&lt;property name="locations">
	   &lt;list>
           &lt;!--指定属性文件地址，可以在这里定义多个属性文件-->
		  &lt;value>classpath:com/baobaotao/place/car.properties&lt;/value> 
	   &lt;/list>
	&lt;/property>
    &lt;property name="fileEncoding" value="utf-8"/>
&lt;/bean>

&lt;!--引用外部属性的值，对car属性进行配置-->
&lt;bean id="car" class="com.baobaotao.place.Car">
	&lt;property name="brand" value="${brand}" />
	&lt;property name="maxSpeed" value="${maxSpeed}" />
	&lt;property name="price" value="${price}" />
&lt;/bean>
</pre><br /><br />使用Spring 2.1后，你只需要象下面这样配置就可以了：<br /><pre name="code" class="java">
&lt;context:property-placeholder location=" classpath:com/baobaotao/place/car.properties "/>
</pre><br /><br />3.注解驱动的Bean注入<br /><br />大家看看这段E文就OK了，<br />&lt;context:component-scan>: scans classpath using one or more "include"/"exclude" filters, and automatically registers beans <br />In essence, this is a third way to define beans (1: classic xml, 2:javaconfig (code), 3:&lt;context:component-scan>, matching on annotations or types) <br />Default naming strategy is based on short classname of discovered bean <br />@Component and @Repository annotations, when used, can optionally specify a bean name to use <br />For filter type "annotation", the value of "expression" attribute should resolve to a Java annotation type <br />For filter type "assignable", the value of "expression" attribute should resolve to a Java type <br />For filter type "aspectj", the value of "expression" should be an "type expression" (in Pointcut language, perhaps it could be injected?) <br />Relevant documentation can be found in preliminary spring 2.1 manual, sections 3.10 and 3.11 <br />In addition, this last JIRA comment for http://www.jetbrains.net/jira/browse/IDEADEV-16886#action_163502 contains two links to articles showing example usage of &lt;context:component-scan> <br />&lt;context:annotation-config> (described in 3.10 in spring 2.1 manual linked above): allows autowiring to be defined using @Resource or @Autowired annotations.<br /><br /><br /><strong>五、关于Spring 2.5添加的新功能</strong><br />&nbsp; Spring 2.5继续对context命名空间进行了扩充，添加了好用而强大的context:load-time-weaver，可以让我们更方便地应用AspectJ。大家可以看TSS上的这篇文章，它全面讲解了Spring 2.5的新特性。<br /><a href="http://www.theserverside.com/tt/articles/article.tss?l=IntrotoSpring25" target="_blank">http://www.theserverside.com/tt/articles/article.tss?l=IntrotoSpring25</a><br /><br /><span style="color: red">注：以上大部分代码来直接引用自 《精通Spring 2.x--企业应用开发精解》</span>
          <br/><br/>
          <span style="color:red;">
            <a href="http://stamen.javaeye.com/blog/148519#comments" style="color:red;">已有 <strong>1</strong> 人发表留言，猛击-&gt;&gt;<strong>这里</strong>&lt;&lt;-参与讨论</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;">Windows7在微软WinHEC 2008上揭开神秘面纱</span></a></li><li><a href='/adverts/138' target='_blank'><span style="color:red;font-weight:bold;">加入阿里巴巴，发展潜力无限</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sat, 15 Dec 2007 11:20:57 +0800</pubDate>
        <link>http://stamen.javaeye.com/blog/148519</link>
        <guid>http://stamen.javaeye.com/blog/148519</guid>
      </item>
          <item>
        <title>一个难解的问题</title>
        <author>stamen</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://stamen.javaeye.com">stamen</a>&nbsp;
                    链接：<a href="http://stamen.javaeye.com/blog/135770" style="color:red;">http://stamen.javaeye.com/blog/135770</a>&nbsp;
          发表时间: 2007年10月26日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          我需要通过服务端的JSON生成EXT的Tree，EXT Tree的JSON数据结构如下所示：<br /><pre name="code" class="java">new Ext.tree.TreePanel({
    id:'favorite-tree',
    border:false,
    loader: new Tree.TreeLoader({&lt;----①
           dataUrl:'loadData.do?act=getChildren&amp;node=2222'				}),					                    		rootVisible:false,					
         lines:true,
	root: new Ext.tree.AsyncTreeNode({  &lt;----②
               text: 'ddd',
               draggable:false,
               id:'source',
	      children:[								               {                                           
	                 leaf : true,   
	                 text:'bbb',   
	                 href: "javascript:showTab('menu1','aaa', 'config.spr')"  
	               },
                        {                                           
	                 leaf : true,   
	                 text:'bbb',   
	                 href: "javascript:showTab('menu1','aaa', 'config.spr')"  
	               }
                         ]})
      });</pre><br /><br />&nbsp;&nbsp;&nbsp; 我们知道使用JSON-lib生成的属性可以是基本数据类型（int、boolean,string等）、对象生成为{},数组生成为[],而String中直接带function()时，Json-lib也会直接生成为aaa:function(){...}<br />的样式，但是如何让属性是一个带new的JS对象呢（如①，②所示的样式）？<br />&nbsp;&nbsp;&nbsp;&nbsp; 请知道的朋友相助一下，谢谢！
          <br/><br/>
          <span style="color:red;">
            <a href="http://stamen.javaeye.com/blog/135770#comments" style="color:red;">已有 <strong>4</strong> 人发表留言，猛击-&gt;&gt;<strong>这里</strong>&lt;&lt;-参与讨论</a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/138' 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/41' target='_blank'><span style="color:red;font-weight:bold;">Windows7在微软WinHEC 2008上揭开神秘面纱</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Fri, 26 Oct 2007 16:27:23 +0800</pubDate>
        <link>http://stamen.javaeye.com/blog/135770</link>
        <guid>http://stamen.javaeye.com/blog/135770</guid>
      </item>
          <item>
        <title>Spring JDBC和Hibernate混用时，如何配置事务管理</title>
        <author>stamen</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://stamen.javaeye.com">stamen</a>&nbsp;
                    链接：<a href="http://stamen.javaeye.com/blog/131203" style="color:red;">http://stamen.javaeye.com/blog/131203</a>&nbsp;
          发表时间: 2007年10月11日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          由于我们项目的需求比较变态，一部分功能由于需要通过数据库配置表动态生成持久化逻辑，所以只得采用Spring JDBC，而另一部分的业务数据模型比较固定，所以我打算对这部分使用Hibernate。这样，一个应用系统同时存在Spring JDBC和Hibernate两种持久化技术。<br />&nbsp;&nbsp;&nbsp;&nbsp; 我采用Spring 2.0，通过给注解驱动的方式进行事务管理，也就是说在Service接口中打@Transaction注解，并在配置文件中配置：<br /><pre name="code" class="java">    &lt;bean id="transactionManager"
	class="org.springframework.orm.hibernate3.HibernateTransactionManager">
		&lt;property name="sessionFactory" ref="sessionFactory" />
    &lt;/bean>
    &lt;tx:annotation-driven transaction-manager="transactionManager" /> </pre><br />&nbsp;&nbsp;&nbsp; 但是一个Spring容器只能配置一个配置一种类型的事务管理器，要么使用基于JDBC的<br />&nbsp; DataSourceTransactionManager，要么使用Hibernate的HibernateTransactionManager。<br />&nbsp; 现在我是同时需要DataSourceTransactionManager和HibernateTransactionManager，而<br />&nbsp;&nbsp; &lt;tx:annotation-driven >只允许设置一个事务管理器。如果我要让Spring JDBC和Hibernate<br />&nbsp; 这两种方式共存于一个应用系统中，请问该如何配置呢？<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 不知哪位朋友有遇到过和我相似的问题，请伸出您的热忱双手吧，帮我分析一下，我快疯了：（
          <br/><br/>
          <span style="color:red;">
            <a href="http://stamen.javaeye.com/blog/131203#comments" style="color:red;">已有 <strong>6</strong> 人发表留言，猛击-&gt;&gt;<strong>这里</strong>&lt;&lt;-参与讨论</a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/138' target='_blank'><span style="color:red;font-weight:bold;">加入阿里巴巴，发展潜力无限</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">Windows7在微软WinHEC 2008上揭开神秘面纱</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, 11 Oct 2007 20:28:15 +0800</pubDate>
        <link>http://stamen.javaeye.com/blog/131203</link>
        <guid>http://stamen.javaeye.com/blog/131203</guid>
      </item>
          <item>
        <title>有没有办法获取浏览器中缓存的条目</title>
        <author>stamen</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://stamen.javaeye.com">stamen</a>&nbsp;
                    链接：<a href="http://stamen.javaeye.com/blog/120182" style="color:red;">http://stamen.javaeye.com/blog/120182</a>&nbsp;
          发表时间: 2007年09月04日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          当访问一个页面时，浏览器会在本地临时目录中（如：C:\Documents and Settings\Administrator\Local Settings\Temporary Internet Files）缓存网页的内容，如HTML ，JS ，图片等，以便下次访问时提高效率。我们知道可以通过JS获取缓存在这个目录下的Cookie，不知道有没有办法通过JS获取某个特定网站的所有本地缓存条目呢？<br />&nbsp;&nbsp;&nbsp; 我现在能想到的一个方法是通过Js的ActiveX对象FileSystemObject来访问，不过存在两个问题：<br /> 1)需要客户同意，开放权限才可以；<br /> 2)临时目录对于不同操作系统，不同用户登录时，都会放在不同的目录下面，编写兼容程序比较困难<br />&nbsp;&nbsp; <br />&nbsp;&nbsp; 有更好的建议吗？谢谢！！
          <br/><br/>
          <span style="color:red;">
            <a href="http://stamen.javaeye.com/blog/120182#comments" style="color:red;">已有 <strong>4</strong> 人发表留言，猛击-&gt;&gt;<strong>这里</strong>&lt;&lt;-参与讨论</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/138' target='_blank'><span style="color:red;font-weight:bold;">加入阿里巴巴，发展潜力无限</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">Windows7在微软WinHEC 2008上揭开神秘面纱</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Tue, 04 Sep 2007 11:38:01 +0800</pubDate>
        <link>http://stamen.javaeye.com/blog/120182</link>
        <guid>http://stamen.javaeye.com/blog/120182</guid>
      </item>
          <item>
        <title>请问Ext的Ext.TabPanel支持iframe吗</title>
        <author>stamen</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://stamen.javaeye.com">stamen</a>&nbsp;
                    链接：<a href="http://stamen.javaeye.com/blog/111264" style="color:red;">http://stamen.javaeye.com/blog/111264</a>&nbsp;
          发表时间: 2007年08月11日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          我原来使用 dhtmlxTabbar，这个控件对Tab页的支持真是一流的棒，几乎所有的需要都可以得到满足，比较你可以让一个Tab页对应一个iframe，这样Tab页中内容的提交就可以不影响其它Tab页了。<br />&nbsp; 下面是dhtmlxTabbar控制使用 iframe模式的代码：<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br /><pre name="code" class="java">         //创建一个tabbar
         tabbar=new dhtmlXTabBar("content","top");
        tabbar.setImagePath("/imgs/");
        tabbar.setStyle("modern");
        tabbar.setHrefMode("iframes");//每一个Tab页对应一个新的iframe

        //添加一个Tab页
         vat tabId = "1",tabName="tab1";
        tabbar.addTab(tabId,tabName,"100px",0);
        _targetUrl = "http://www.baobaotao.com";
        tabbar.setContentHref(tabId,_targetUrl);</pre><br />&nbsp;&nbsp; 我试了Ext的Tab控件，目前我还没有发现可以一个Tab页对应一个iframe的，不知道是否可以支持一个<br />Tab页一个iframe。请有知道的朋友赐教，谢谢。
          <br/><br/>
          <span style="color:red;">
            <a href="http://stamen.javaeye.com/blog/111264#comments" style="color:red;">已有 <strong>22</strong> 人发表留言，猛击-&gt;&gt;<strong>这里</strong>&lt;&lt;-参与讨论</a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/138' 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/41' target='_blank'><span style="color:red;font-weight:bold;">Windows7在微软WinHEC 2008上揭开神秘面纱</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sat, 11 Aug 2007 16:28:07 +0800</pubDate>
        <link>http://stamen.javaeye.com/blog/111264</link>
        <guid>http://stamen.javaeye.com/blog/111264</guid>
      </item>
          <item>
        <title>欢迎大家探讨对Spring Web Flow的评价</title>
        <author>stamen</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://stamen.javaeye.com">stamen</a>&nbsp;
                    链接：<a href="http://stamen.javaeye.com/blog/87332" style="color:red;">http://stamen.javaeye.com/blog/87332</a>&nbsp;
          发表时间: 2007年06月06日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          个人觉得Spring Web Flow只是增加开发的复杂度，本来可以通过简单的硬编辑完成的东西，为什么硬要搞出一个配置文件来，大家看看Spring Web Flow给的那个例子（<a href="http://www.ervacon.com/products/springwebflow/article/index.html" target="_blank">http://www.ervacon.com/products/springwebflow/article/index.html</a>），根据查询用户，然后显示详细信息的例子，本来很简单的东西 ，硬是变得复杂了许多，不但多出了很多类不多，还多出了许多配置的信息，更让人纳闷的是Spring MVC该做的东西还一件都不能少。<br />&nbsp;&nbsp; <br />&nbsp;&nbsp; 页面控制流真的会那么复杂吗？SFW除了能够通过一个配置文件显式将隐藏在硬编码中的页面控制流程描述出来外，其它的贡献，我总觉得很廖廖。但是我们为什么一定要在程序中通过一个配置文件烘托出页面控制流程呢？－－这更象是在写文档时该做的事情。<br /><br />&nbsp;&nbsp; 也许是我一已的偏见，或是此时对SWF的认识还不够清晰，请使用过SWF并感受其真的给开发带来简化的朋友谈谈感受。不欢迎人云亦云的泛泛而谈，希望看到你真实的感受的实际的经验的交流。
          <br/><br/>
          <span style="color:red;">
            <a href="http://stamen.javaeye.com/blog/87332#comments" style="color:red;">已有 <strong>18</strong> 人发表留言，猛击-&gt;&gt;<strong>这里</strong>&lt;&lt;-参与讨论</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;">Windows7在微软WinHEC 2008上揭开神秘面纱</span></a></li><li><a href='/adverts/138' 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, 06 Jun 2007 11:18:21 +0800</pubDate>
        <link>http://stamen.javaeye.com/blog/87332</link>
        <guid>http://stamen.javaeye.com/blog/87332</guid>
      </item>
          <item>
        <title>请问在FreeMarker中如何引用JSTL标签</title>
        <author>stamen</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://stamen.javaeye.com">stamen</a>&nbsp;
                    链接：<a href="http://stamen.javaeye.com/blog/84520" style="color:red;">http://stamen.javaeye.com/blog/84520</a>&nbsp;
          发表时间: 2007年05月29日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          JSTL的&lt;c:url="ddd"/>标签可以得到应用程序的部署目录，但是FreeMarker中如何知识应用程序的部署目录呢？在Google和Baidu以及各大论坛都狂搜索了一气，可以还是没有结果。<br />&nbsp;&nbsp;&nbsp; http://smile6688.javaeye.com/blog/49642 说明了FreeMarker引用Struts标签的方法，不知道FreeMarker能否引用JSTL的标签，如何引用呢？或者有没有什么办法可以在FreeMarker中使用类似于JSTL的&lt;c:url="ddd"/>功能。<br />&nbsp;&nbsp; 非常感谢！
          <br/><br/>
          <span style="color:red;">
            <a href="http://stamen.javaeye.com/blog/84520#comments" style="color:red;">已有 <strong>9</strong> 人发表留言，猛击-&gt;&gt;<strong>这里</strong>&lt;&lt;-参与讨论</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;">Windows7在微软WinHEC 2008上揭开神秘面纱</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/138' target='_blank'><span style="color:red;font-weight:bold;">加入阿里巴巴，发展潜力无限</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Tue, 29 May 2007 17:33:10 +0800</pubDate>
        <link>http://stamen.javaeye.com/blog/84520</link>
        <guid>http://stamen.javaeye.com/blog/84520</guid>
      </item>
          <item>
        <title>问题：Spring基于@AspectJ参数绑定的原理</title>
        <author>stamen</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://stamen.javaeye.com">stamen</a>&nbsp;
                    链接：<a href="http://stamen.javaeye.com/blog/50894" style="color:red;">http://stamen.javaeye.com/blog/50894</a>&nbsp;
          发表时间: 2007年01月28日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          Spring 2.0提供了基于@AspectJ和Schema的AOP配置，有一个问题一直让我很郁闷,那就是增强方法是如何绑定到目标类连接点方法的入参的，Spring通过argNames成员指定入参名来绑定连接点的入参，在Spring的文档中说argNames是为了明确绑定入参名，请看下面的代码：<br /><pre name="code" class="java">	@Before("target(com.baobaotao.NaiveWaiter) &amp;&amp; args(name,num,..)",argsName="name,num")
	public void bindJoinPointParams(int num,String name){
	   System.out.println("----bindJoinPointParams()----");
	   System.out.println("name:"+name);
	   System.out.println("num:"+num);
	   System.out.println("----bindJoinPointParams()----");
	}</pre><br />&nbsp;&nbsp; 在切点表达式中，通过args(name,num,..)绑定了两个连接点方法的参数，一个匹配的连接点方法如下：<br /><pre name="code" class="java">package com.baobaotao;
public class NaiveWaiter implements Waiter {
   public void smile(String name,int num){
	System.out.println("NaiveWaiter:smile to  "+name+ num+"times...");
   }	
}</pre><br />&nbsp;&nbsp; 上面的切点，将name和num分别绑定到增强方法的name和num参数中.<br />&nbsp;&nbsp; 我的问题是，既然args(name,num,..)已经指定了参数名，为什么还需要通过argsName再次声明参数名呢？Spring文档告诉我们：argsName是明确绑定的参数名，说是反射机制无法获取入参名。关键是这种明确的指定有两个问题：<br /><br /><span style="color: red">&nbsp;&nbsp; 1)首先，这里指定的信息和切点表达式中args(name,num)中指定的信息是重复的；<br />&nbsp;&nbsp; 2)其次，我们无法通过反射机制获取目标类连接点smile(String name,int num)参数名，在切面定义中明确指定入参名又有什么意思呢？这好比说，张三和歪毛已经消了名，现在我们确以张三歪毛为线索去查找两人，这有用吗？</span><br /><br />&nbsp;&nbsp; 实际上，我们将切点定义处的argNames成员去除，我发现效果是一样的，它照样可以成功绑定。这个问题的本质是既然Java反射机制无法获取入参名，Spring到底是用了何种神秘的机制，获取方法入参名，因为增强方法和目标连接点方法是通过名称关联绑定的，而不是通过类型绑定的。解决了这个问题后，另一个问题才是为什么需要提供argName这个搞怪的成员做重复性的声明工作。
          <br/><br/>
          <span style="color:red;">
            <a href="http://stamen.javaeye.com/blog/50894#comments" style="color:red;">已有 <strong>1</strong> 人发表留言，猛击-&gt;&gt;<strong>这里</strong>&lt;&lt;-参与讨论</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;">Windows7在微软WinHEC 2008上揭开神秘面纱</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/138' target='_blank'><span style="color:red;font-weight:bold;">加入阿里巴巴，发展潜力无限</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sun, 28 Jan 2007 10:06:33 +0800</pubDate>
        <link>http://stamen.javaeye.com/blog/50894</link>
        <guid>http://stamen.javaeye.com/blog/50894</guid>
      </item>
          <item>
        <title>谁能说说@AspectJ中this和target这两个切点标识符的具体区别</title>
        <author>stamen</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://stamen.javaeye.com">stamen</a>&nbsp;
                    链接：<a href="http://stamen.javaeye.com/blog/49492" style="color:red;">http://stamen.javaeye.com/blog/49492</a>&nbsp;
          发表时间: 2007年01月23日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          Spring Reference对这两个切点标识符的用法描述得不太清楚：<br /><div class="quote_title">引用</div><div class="quote_div">this - limits matching to join points (the execution of methods when using Spring AOP) where the bean<br />reference (Spring AOP proxy) is an instance of the given type<br />• target - limits matching to join points (the execution of methods when using Spring AOP) where the target<br />object (application object being proxied) is an instance of the given type</div><br />&nbsp;&nbsp; 似乎看不出两者的具体区别，我试着做了一个测试：<br />&nbsp;&nbsp; 切面定义类：<br /><br /><pre name="code" class="java">package com.baobaotao.expression;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
@Aspect
public class PreGreetingAspect{
	@Before("target(com.baobaotao.expression.NaiveWaiter)")
	public void beforeGreeting(){
		System.out.println("How are you");
	}
}</pre><br />目标类接口：<br /><pre name="code" class="java">package com.baobaotao.expression;

public interface Waiter {
	public void greetTo(String name);	
	public void serveTo(String name);
}</pre><br />目标接口实现类：<br /><pre name="code" class="java">package com.baobaotao.expression;

public class NaiveWaiter implements Waiter {
	public void greetTo(String name) {
		System.out.println("greet to "+name+"...");
	}	
	public void serveTo(String name){
		System.out.println("serving "+name+"...");
                   foo(name);
	}
	public void foo(String name){
		System.out.println("foo "+name+"...");
	}	
}</pre><br /><br />然后是配置：<br /><pre name="code" class="java">&lt;aop:aspectj-autoproxy />
&lt;bean id="waiter" class="com.baobaotao.expression.NaiveWaiter" />
&lt;bean id="greetingAfter" class="com.baobaotao.expression.PreGreetingAspect" />	</pre><br />最后是测试：<br /><pre name="code" class="java">package com.baobaotao.expression;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.baobaotao.expression.Waiter;
public class TestExpression {
	public static void main(String[] args) {
		String configPath = "com/baobaotao/expression/beans.xml";
		ApplicationContext ctx = new ClassPathXmlApplicationContext(configPath);
		Waiter waiter = (Waiter)ctx.getBean("waiter");
		waiter.greetTo("John");
		waiter.serveTo("John");
	}
}</pre><br />输出以下信息：<br /><pre name="code" class="java">How are you
greet to John...
How are you
serving John...</pre><br />将切点定义换成：<br />@Before("this(com.baobaotao.expression.Waiter)")<br />输出的效果是完全一样的。<br />&nbsp; 我的分析：<br />我本来以为NaiveWaiter的foo()方法在使用@Before("target(com.baobaotao.expression.NaiveWaiter)")应该也可以织入切面，但是发现不管采用哪种方式只能为Waiter接口织入切面。<br />&nbsp;&nbsp; 请问这两个切点表示符到底有什么区别，我现在看到的是两者好象完全一样。
          <br/><br/>
          <span style="color:red;">
            <a href="http://stamen.javaeye.com/blog/49492#comments" style="color:red;">已有 <strong>7</strong> 人发表留言，猛击-&gt;&gt;<strong>这里</strong>&lt;&lt;-参与讨论</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/138' target='_blank'><span style="color:red;font-weight:bold;">加入阿里巴巴，发展潜力无限</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">Windows7在微软WinHEC 2008上揭开神秘面纱</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Tue, 23 Jan 2007 15:55:33 +0800</pubDate>
        <link>http://stamen.javaeye.com/blog/49492</link>
        <guid>http://stamen.javaeye.com/blog/49492</guid>
      </item>
          <item>
        <title>请教：有谁用过PropertyOverrideConfigurer这个类</title>
        <author>stamen</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://stamen.javaeye.com">stamen</a>&nbsp;
                    链接：<a href="http://stamen.javaeye.com/blog/43550" style="color:red;">http://stamen.javaeye.com/blog/43550</a>&nbsp;
          发表时间: 2007年01月06日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          这是Spring手册中关于该类的使用说明：<br /><div class="quote_title">引用</div><div class="quote_div">另一个bean工厂后置处理器PropertyOverrideConfigurer类似于PropertyPlaceholderConfigurer。但是与后者相比，前者对于bean属性可以有缺省值或者根本没有值。如果起覆盖作用的Properties文件没有某个bean属性的内容，那么将使用缺省的上下文定义。<br /><br />bean工厂并不会意识到被覆盖，所以仅仅察看XML定义文件并不能立刻知道覆盖配置是否被使用了。在多个PropertyOverrideConfigurer实例中对一个bean属性定义了不同的值时，最后定义的值将被使用（由于覆盖机制）。<br /><br />Properties文件的配置应该是如下的格式：<br /><br />beanName.property=value<br />一个properties文件可能是下面这样的：<br /><br />dataSource.driverClassName=com.mysql.jdbc.Driver<br />dataSource.url=jdbc:mysql:mydb<br />这个示例文件可用在这样一个bean容器：包含一个名为dataSource的bean，并且这个bean有driver和url属性。<br /><br />注意它也支持组合的属性名称，只要路径中每个组件除了最后要被覆盖的属性外全都是非空的（比如通过构造器来初始化），在下例中：<br /><br />foo.fred.bob.sammy=123<br />foo bean的fred属性的bob属性的sammy属性被设置为数值123。</div><br />&nbsp;&nbsp; 可是，我按着上面配置，Spring却报告错误，没有成功配置，下面把我的实验，简单介绍一下：<br /><pre name="code" class="java">	&lt;bean class="org.springframework.beans.factory.config.PropertyOverrideConfigurer">
	  &lt;property name="locations">
			&lt;list>
				&lt;value>classpath:com/baobaotao/place/car.properties&lt;/value>
			&lt;/list>
	  &lt;/property>
	&lt;/bean>
	&lt;bean id="car" class="com.baobaotao.place.Car">
	   &lt;property name="price" value="100"/>
	   &lt;property name="maxSpeed" value="120"/>
	&lt;/bean></pre><br />&nbsp; Car的类代码如下：<br /><pre name="code" class="java">package com.baobaotao.place;

public class Car {
	private int maxSpeed;
	public String brand;
	private double price;
   //get/setter
}</pre><br />car.properties这个属性文件如下：<br /><pre name="code" class="java">car.maxSpeed=250
car.price=20000.00</pre><br />&nbsp; Spring报出的错误如下：<br /><pre name="code" class="java">org.springframework.beans.factory.BeanInitializationException: Could not process key '﻿car.maxSpeed' in PropertyOverrideConfigurer; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named '﻿car' is defined
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named '﻿car' is defined
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:338)
	at org.springframework.beans.factory.config.PropertyOverrideConfigurer.applyPropertyValue(PropertyOverrideConfigurer.java:139)
	at org.springframework.beans.factory.config.PropertyOverrideConfigurer.processKey(PropertyOverrideConfigurer.java:127)
	at org.springframework.beans.factory.config.PropertyOverrideConfigurer.processProperties(PropertyOverrideConfigurer.java:99)
	at org.springframework.beans.factory.config.PropertyResourceConfigurer.postProcessBeanFactory(PropertyResourceConfigurer.java:75)
	at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:414)
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:328)
	at org.springframework.context.support.ClassPathXmlApplicationContext.&lt;init>(ClassPathXmlApplicationContext.java:92)
	at org.springframework.context.support.ClassPathXmlApplicationContext.&lt;init>(ClassPathXmlApplicationContext.java:77)
	at com.baobaotao.place.TestPropertyPlace.setUp(TestPropertyPlace.java:17)
...
</pre><br />&nbsp;&nbsp; 不知有没有使用过该类的朋友，请分享一下经验，谢谢！
          <br/><br/>
          <span style="color:red;">
            <a href="http://stamen.javaeye.com/blog/43550#comments" style="color:red;">已有 <strong>7</strong> 人发表留言，猛击-&gt;&gt;<strong>这里</strong>&lt;&lt;-参与讨论</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;">Windows7在微软WinHEC 2008上揭开神秘面纱</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/138' target='_blank'><span style="color:red;font-weight:bold;">加入阿里巴巴，发展潜力无限</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sat, 06 Jan 2007 21:59:05 +0800</pubDate>
        <link>http://stamen.javaeye.com/blog/43550</link>
        <guid>http://stamen.javaeye.com/blog/43550</guid>
      </item>
          <item>
        <title>困惑：谁能帮我解答一个关于BeanWrapperImpl设计的问题</title>
        <author>stamen</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://stamen.javaeye.com">stamen</a>&nbsp;
                    链接：<a href="http://stamen.javaeye.com/blog/43048" style="color:red;">http://stamen.javaeye.com/blog/43048</a>&nbsp;
          发表时间: 2007年01月04日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          最近在分析Spring的源码，但对其中一个问题很困惑，现描述如下，希望各位帮忙分析一下：<br />&nbsp;&nbsp; 在IoC容器实例化Bean后，Bean只是个半成品，IoC容器将调用BeanWrapper的实现类BeanWrapperImp对这个实例进行属性值填充的后续工作。BeanWrapperImpl的类结构如下所示：<br /><pre name="code" class="java">           PropertyEditorRegistry
                         |
               PropertyEditorRegistrySupport
                         |
BeanWrapper    AbstractPropertyAccessor
     |                   |
     |___________________|
                         |
                   BeanWrapperImpl</pre><br />&nbsp;&nbsp; 在PropertyEditorRegistrySupport中定义了两个Map类型的defaultEditors和customEditors，用于存放常见类型（String Integer等原子类型）和自定义类型的属性编辑器。<br /><pre name="code" class="java">   	private Map defaultEditors;
	private Map customEditors;</pre><br />&nbsp;&nbsp; 所以，BeanWrapperImpl也拥有继承了这些编辑器，但是我有一点不明白的是，为什么BeanWrapperImpl不是容器级的，而是Bean级的：即在容器主控制程序中，每实例化一个Bean时，都要new一个BeanWrapperImpl实例出来，请看：<br /><pre name="code" class="java">	protected BeanWrapper instantiateBean(String beanName, 
                       RootBeanDefinition mergedBeanDefinition) 
                   throws BeansException {

		Object beanInstance = getInstantiationStrategy().instantiate(mergedBeanDefinition, beanName, this);
		<strong>BeanWrapper bw = new BeanWrapperImpl(beanInstance);</strong>
		initBeanWrapper(bw);
		return bw;
	}</pre><br />&nbsp;&nbsp;&nbsp; 这样一来属性编辑器的实例会被多次创建，因为每个BeanWrapperImpl对应一套属性编辑器，而在我看来这些属性编辑器应该是容器级的，也就是说只要保存一份就可以了，现在的情况是每创建一个Bean都对应一份，不但没有必要，而且浪费资源。<br />&nbsp;&nbsp;&nbsp; 不知道是我没有看出其中的机巧，还是Rod的设计失误，请大家帮助分析一下，不胜感激。
          <br/><br/>
          <span style="color:red;">
            <a href="http://stamen.javaeye.com/blog/43048#comments" style="color:red;">已有 <strong>9</strong> 人发表留言，猛击-&gt;&gt;<strong>这里</strong>&lt;&lt;-参与讨论</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;">Windows7在微软WinHEC 2008上揭开神秘面纱</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/138' target='_blank'><span style="color:red;font-weight:bold;">加入阿里巴巴，发展潜力无限</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Thu, 04 Jan 2007 17:25:14 +0800</pubDate>
        <link>http://stamen.javaeye.com/blog/43048</link>
        <guid>http://stamen.javaeye.com/blog/43048</guid>
      </item>
          <item>
        <title>谜语：AOP 打一汉字</title>
        <author>stamen</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://stamen.javaeye.com">stamen</a>&nbsp;
                    链接：<a href="http://stamen.javaeye.com/blog/36667" style="color:red;">http://stamen.javaeye.com/blog/36667</a>&nbsp;
          发表时间: 2006年11月30日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          AOP 打一汉字
          <br/><br/>
          <span style="color:red;">
            <a href="http://stamen.javaeye.com/blog/36667#comments" style="color:red;">已有 <strong>9</strong> 人发表留言，猛击-&gt;&gt;<strong>这里</strong>&lt;&lt;-参与讨论</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/138' target='_blank'><span style="color:red;font-weight:bold;">加入阿里巴巴，发展潜力无限</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">Windows7在微软WinHEC 2008上揭开神秘面纱</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Thu, 30 Nov 2006 10:04:36 +0800</pubDate>
        <link>http://stamen.javaeye.com/blog/36667</link>
        <guid>http://stamen.javaeye.com/blog/36667</guid>
      </item>
          <item>
        <title>讨论：Acegi安全框架能解决和不能解决的安全问题</title>
        <author>stamen</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://stamen.javaeye.com">stamen</a>&nbsp;
                    链接：<a href="http://stamen.javaeye.com/blog/32487" style="color:red;">http://stamen.javaeye.com/blog/32487</a>&nbsp;
          发表时间: 2006年11月04日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          就我目前对Acegi的了解，Acegi安全框架主要解决的安全问题是访问入口级别的安全问题，安全问题我将其分为三类：<br />1) <strong>入口级安全</strong><br />&nbsp;&nbsp; 具体体现上界面上每个操作菜单，操作元素是否可操作，在服务端则对URL程序资源和业务服务类方法的限制。<br /><br />2)<strong> 数据域安全</strong><br />&nbsp; 数据域控制包括两个部分，分别是：<br />&nbsp; 2.1 行级数据控制 即可以可以访问哪些数据行，一般的限制项是数据所属单位；<br />&nbsp; 2.2 字段级控制 即用户可以访问数据行的哪些字段；<br /><br />3)<strong>系统级安全</strong><br />&nbsp; 如访问IP段的限制，登录时间段的限制，登录次数的限制等。<br /><br />&nbsp;&nbsp;&nbsp; Acegi由于和业务无关，所以只能解决1)点的安全问题，2),3)的安全问题是和业务，组织机构相关的，所以必须程序编码解决。<br />&nbsp;&nbsp;&nbsp; 严格上说，Acegi对1)点的解决也是不彻底的，因为它只解决了服务端的程序资源访问控制，操作界面上的元素是要我们编码实现的。不过，这也好理解，因为界面的入口元素是最灵活多样的，Acegi不应该涉足。<br />所以我觉得Acegi在一个很适合的领域时，很好的解决了一些适合框架解决的问题，它不贪恋那些不容易框架实现而需求变化大多的问题。
          <br/><br/>
          <span style="color:red;">
            <a href="http://stamen.javaeye.com/blog/32487#comments" style="color:red;">已有 <strong>5</strong> 人发表留言，猛击-&gt;&gt;<strong>这里</strong>&lt;&lt;-参与讨论</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;">Windows7在微软WinHEC 2008上揭开神秘面纱</span></a></li><li><a href='/adverts/138' target='_blank'><span style="color:red;font-weight:bold;">加入阿里巴巴，发展潜力无限</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sat, 04 Nov 2006 22:01:16 +0800</pubDate>
        <link>http://stamen.javaeye.com/blog/32487</link>
        <guid>http://stamen.javaeye.com/blog/32487</guid>
      </item>
          <item>
        <title>讨论：Dao查询接口设计经验</title>
        <author>stamen</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://stamen.javaeye.com">stamen</a>&nbsp;
                    链接：<a href="http://stamen.javaeye.com/blog/32262" style="color:red;">http://stamen.javaeye.com/blog/32262</a>&nbsp;
          发表时间: 2006年11月02日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          接受若干查询条件的DAO查询方法接口在实际应用中，大家不知道是如何设计，下面是我所了解的4种定义方法：<br /><br />1)<strong>为查询参数定义对象，如：</strong><br />&nbsp; queryOrder(OrderQueryParam oqp)&nbsp;&nbsp; <br />&nbsp; OrderQueryParam为每一个查询条件项定义一个属性如：<br />&nbsp; Date startTime<br />&nbsp; Date endTime<br />&nbsp; int orderNo<br />&nbsp; int deptId<br />&nbsp; 这种方式的优点是直观，接口清晰且稳定，但是需要定义大量的查询参数对象，比较麻烦。<br /><br />2)<strong>用一个Map封装所有查询条件，如：</strong><br />&nbsp; queryOrder(Map filterMap)<br />&nbsp; 每一个查询条件项对应filterMap中一个元素<br />&nbsp; key&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; value<br />&nbsp; ----------------<br />&nbsp; startTime 20060101<br />&nbsp; endTime&nbsp;&nbsp; 20061201<br />&nbsp; deptId&nbsp;&nbsp; 1002<br />&nbsp; 这种方式的接口签名也是稳定的，其他的优点和缺点正好和1)点相反 <br /><br />3)<strong>每一个条件项对应一个入参，如：</strong><br />&nbsp; queryOrder(Date startTime,Date endTime,int orderNo,int deptId)<br />&nbsp; 这种方式的接口签名不稳定，假如要加一个userId的条件，接口就得改了，但是接口也是比较清晰的。<br /><br />4)<strong>使用JDK5.0中提供的不定数入参，如：</strong><br />&nbsp; queryOrder(String hql ,Object... args)<br />&nbsp; 在该中方法中：（需要注意args的顺序和hql中变量的顺序一致），组装Hql的核心代码如下：<br />&nbsp; Query query = getSession().createQuery(hql);<br />&nbsp; for (int i = 0; i &lt; args.length; i++) {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; query.setParameter(i, args[i]);<br />&nbsp; }<br />&nbsp; 这种方式接口签名也是稳定的，不过接口也是不清晰。&nbsp; <br /><br />&nbsp;&nbsp; 不知道大家在实践中还有没有其他好的方法，欢迎抛玉！！
          <br/><br/>
          <span style="color:red;">
            <a href="http://stamen.javaeye.com/blog/32262#comments" style="color:red;">已有 <strong>21</strong> 人发表留言，猛击-&gt;&gt;<strong>这里</strong>&lt;&lt;-参与讨论</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/138' target='_blank'><span style="color:red;font-weight:bold;">加入阿里巴巴，发展潜力无限</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">Windows7在微软WinHEC 2008上揭开神秘面纱</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Thu, 02 Nov 2006 22:30:23 +0800</pubDate>
        <link>http://stamen.javaeye.com/blog/32262</link>
        <guid>http://stamen.javaeye.com/blog/32262</guid>
      </item>
          <item>
        <title>和一个朋友的聊天，他比较排斥Spring</title>
        <author>stamen</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://stamen.javaeye.com">stamen</a>&nbsp;
                    链接：<a href="http://stamen.javaeye.com/blog/31046" style="color:red;">http://stamen.javaeye.com/blog/31046</a>&nbsp;
          发表时间: 2006年10月29日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          此处省去废话100行：）<br /><br />Unknow---- says:<br />你可以从spring的价值来考虑下..我对spring在项目的应用所带来的价值还是有怀疑..<br /><br />Stamen says:<br />你选Acegi做权限 很适合 我的判断是一定可以胜任行业性的系统<br /><br />Stamen says:<br />Spring我用得越深 发现他的实用性更好 你可以花时间多了解 再做判断。<br /><br />Unknow---- says:<br />你说来看看,spring的价值<br /><br />Stamen says:<br />Spring 2.0对配置做了大副的简化，而且你所说的契约模式 Spring是可以实现的<br /><br />Stamen says:<br />我觉得主要有以下几点：<br /><br />Unknow---- says:<br />还没写完哦..<br /><br />Stamen says:<br />1)使类充分解耦，不需硬编码的方式 设计类和类之间的关系，它带来的好处是，你可以随时替换关联者，而无需动代码；<br />2)由于类都在Spring容器中统一管理，为加入切面编程提供了可能，业务对象从事务，安全性，日志等代码等非业务性的代码中脱离出来，业务类更简洁 只关注业务；<br />3)Spring使你更加方便地使用常用企业功能，如JavaMail，Timer，远程调用，缓存，安全等，Spring使得利用这些类库得到了很大的简化，而如果你直接用这些类库，学习曲线陡峭得很多；<br /><br /><br />Stamen says:<br />4)Spring使测试更加容易，对于Web的应用，它提供了很多Mock测试类，无需启动Web服务<br /><br />Stamen says:<br />5)还有很多待发现的好处... <br /><br />Unknow---- says:<br />第一点应该是spring的最核心的价值,也是最初的价值..但这点的实用价值在我们做项目中,真的有用吗?<br /><br />Stamen says:<br />第一点 在一般项目中实用性并不明显<br /><br />Unknow---- says:<br />第二点,切面所带来的思想远远比现在所带来的价值大..他的价值是什么.能带来多大的价值哦<br /><br />Stamen says:<br />它更象是框架级的东西<br /><br />Unknow---- says:<br />第三点是有价值了<br /><br />Unknow---- says:<br />第四点易测试,,也是看项目如何做了..<br /><br />Stamen says:<br />我觉得 第2点是工程性项目最有价值的地方，事务，安全，日志代码的拨离 太太提高了代码生产率<br /><br />Unknow---- says:<br />事务,其实作用不大了..<br /><br />Unknow---- says:<br />用配置的事务,可比用写代码的麻烦了..<br /><br />Stamen says:<br />你看看Acegi就好了，它就是将程序的访问控制剥离出来 在业务代码中根据看不看访问控制的痕迹 ，这点太伟大了。<br /><br />Stamen says:<br />“用配置的事务,可比用写代码的麻烦了..”只能说明你对Spring不够了解<br /><br />Unknow---- says:<br />就是安全还可以有参考的价值..但我们做业务系统,很多是在界面控制权限的..而ACEGI是在服务端控制的..<br /><br />Unknow---- says:<br />为什么这么说?<br /><br />Unknow---- says:<br />你用配置的事务,比写代码的,有用的价值体现在哪<br /><br />Stamen says:<br />Spring2.0提供了简洁的事务配置，利用AspectJ来做事务，配置的简化是数量级的，你可以看看这方面的资料<br /><br />Unknow---- says:<br />能简洁到什么程度?<br /><br />Stamen says:<br />首先，我觉得配置不是首要问题，首要问题是业务对象只需要关心业务逻辑才是关键中的关键<br /><br />Unknow---- says:<br />这个从思想上没错,我一直认同这点..其实这点从根本上讲就是单一职责原则,无论是分层,还是把事务,安全,日志从业务中的抽取都是体现这点.<br /><br />Stamen says:<br />业务对象只做自己手头上的工作，自己的工作究竟如何被组织起来完成一件“大事”业务对象不用去关心，这样业务对象的逻辑就大大简化了，我举一个例子，象69年的阿波罗登月项目 ，参加的单位，组织，学校有上千个，人有11万多，上面有一个总调度人总揽全局（Spring），而各个单位只负责自己手头的事，甚至某些单位只是简单按标准做好了螺丝钉。如果没有总揽大局的协调者，那么每个单位都需要双方去协调事务，那么项目的复杂度马上不能控制了。<br /><br /><br />Unknow---- says:<br />但我觉的更要从实用性考虑..就像EJB一样,它所体现的思想不错,但实用性太差了,所以被市场抛弃了<br /><br /><br />Stamen says:<br />EJB的复杂不在于声明事务，相反声明事务是EJB最大的亮点，EJB的复杂在于它和容器捆绑太死，以至于在开发中的测试上非常困难。<br /><br /><br />Stamen says:<br />测试的方便性直接影响到开发的效率，Spring比之EJB最大的提升就是易测试上，其次就是使POJO可以使用声明事务<br /><br /><br />Unknow---- says:<br />但它的思想是体现在组件思想上..这是它的核心思想,但EJB的实现很糟糕,所以开发人员使用时,实用价值太低了.所以被抛弃了..<br /><br /><br />Unknow---- says:<br />而SPRING的思想就是你提到的,问题是我们在项目中使用spring,真正能带来的实用价值是多大..这点才是最关键的..<br /><br /><br />Stamen says:<br />不管是组件也好 POJO也好 如果它易测试 易部署 对于实际的开发和应用 负面影响倒不会太大 <br /><br /><br />Unknow---- says:<br />就像声明式事务,在我们以前所做的业务系统中,能比我们以前的方式带来多大价值,不是指思想上.而是指实用上..<br /><br /><br />Unknow---- says:<br />你所提到的易测试性,也很不错,这也是我以前所总结过的.<br /><br /><br />Stamen says:<br />价值就是简洁代码开发 提高项目进度 这难道还是不实实在在的价值吗<br /><br /><br />Unknow---- says:<br />spring在实现时,考虑到了易测试性,很好..所以作者真的是实战思想家<br /><br /><br />Stamen says:<br />你去拿一个模块，一个自己写事务管理 一个用Spring声明事务 比较两者的代码行 两者的开发效率 就一目了然了。<br /><br />Unknow---- says:<br />简化代码,问题是简花了多少代码,其实我们在做业务系统中,事务很少为我们项目带来麻烦..很少BUG是由事务的问题带来的..而采用基于配置的事务,必须要运行时才能测试事务的完整性吧..<br /><br />Stamen says:<br />叫程序员去一遍一遍写没有思想的事务管理代码本身就是一种人力资源甚至是智力资源的浪费。<br /><br />Unknow---- says:<br />而且如果我们采用统一风格的事务,我们完全可以做到在一个地方写事务控制的代码,业务逻辑不需要涉及事务,可能更简单..<br /><br />Stamen says:<br />一个地方写事务控制的代码？？？不太现实<br /><br />Unknow---- says:<br />可以了..其实我们的业务系统很简单了.都是在action控制事务了..我们在commonaction中控制就可以了<br /><br />Unknow---- says:<br />其实内可以考虑配置型事务真正实用的价值所在..<br /><br />Stamen says:<br />哈哈 Action是展现层 展现层去干涉业务，你会被人踢的<br /><br />Unknow---- says:<br />我的理解跟你不一样..事务不是简单的指数据库的事务哦.<br /><br />Stamen says:<br />不管怎么样 事务都是业务层的负责 你把在扩展到展现层 是比较严重的设计缺陷<br /><br />Stamen says:<br />假设Service还有一个C/S应用需要调用 ，或者一个WAP应用需要调用 Service层还能够通用吗<br /><br />Unknow---- says:<br />举个例子吧.用户注册的,用户注册成功,必须要在数据库中插入用户记录和日志记录,还有在每天注册人数增加一,还要发送邮件,如果有一步出错,都要退回,这时候用配置的事务就很难解决了<br /><br />Stamen says:<br />用Spring绝对可以解决你这个需求<br /><br />Unknow---- says:<br />我觉的我们开发人员有一个毛病,就是想很多不存在的需求,所以导致设计偏向了.如果我们只把握最核心的需求,那我们的设计就很简单..所以我觉的设计简单,要比设计可扩展性更要考虑<br /><br />Unknow---- says:<br />我注册失败后,还要让当天注册人数减一..用spring如何解决<br /><br />Stamen says:<br />设计简单要事先满足一定的规范，象你让事务在Action中控制 这就有点过了<br /><br />Unknow---- says:<br />其实你要看action它真正体现的是什么了,我觉的它是事务的发起者和结束者.所以在action中去简化它..就变的容易了..<br /><br />Stamen says:<br />做一个ThrowableAdvice就可以了，当发现用户注册失败异常时，用户注册人数减一<br /><br />Unknow---- says:<br />做切面时,你能调用HttpSession吗<br /><br />Unknow---- says:<br />当天注册人数,我可能要操作用户的session,如何在你的ThrowableAdvice做呢<br /><br />Stamen says:<br />Action是业务服务的调用者，但不是事务控制的管理者 事务是业务的范畴<br /><br />Unknow---- says:<br />如果做一个平台,我会采用基于配置的事务,如果我像平时做业务系统,当然要怎么做最简单就怎么做了.<br /><br />Stamen says:<br />让ThrowableAdvice实现ApplicationContextAware 就可以获取Session了。<br /><br />Unknow---- says:<br />这只是个例子.我觉的spring的思想不错,但很多东西都是刚开始,还没完善,所以如果现在用这些特性,可能把本来很简单的项目弄的很复杂..这是我们做业务系统必须要考虑的..你可以想想用spring做我们以前的业务系统,能不能带来你所说的价值..<br /><br />Stamen says:<br />不会错，简单的业务系统怎么做都可以 你甚至可以只用JSP实现所有功能，关键是为什么大师们都坚持Service和View层要解耦 他们的经验和理解力 已经实践经验都是在我们之上很多倍的<br /><br />Unknow---- says:<br />还有一点你要考虑的,国内的IT环境跟国外的不一样.我觉的这点就带来很大的影响了<br /><br />Unknow---- says:<br />你可以考虑下我们以前的业务系统和采用spring后,你可以对比下..<br /><br />Stamen says:<br />一个东西要用好它就先要搞透它 否则不但得不到简化 可以带来更多坏的影响，就象F22性能虽好 但开不来还如拿大刀 <br /><br />Unknow---- says:<br />很多开发人员都是国外人员提什么技术,国外人员说好,国内的就跟风,我觉的很多开发人员缺乏对技术的鉴证性,就是这个新技术能不能为项目带来生产率和质量的提高,这是最关键的.鉴证性如何考虑呢?有一点很重要,就是实用性,在项目中去实践.. <br /><br />Stamen says:<br />对，国内的开发人员半调儿的太多 稍微培训一下就上路 在学校学的也都是过时的东西 因为没有自己的思想 跟风就比较严重，所以才会有EJB热<br /><br />Unknow---- says:<br />是啊..所以如果一个技术没转眼透,对技术的理解不透彻,都可以对使用这个技术带来错误的判断.也许我犯了这个错误,但至少我还没看到那个人能真正说出在他们的项目中,用spring带来了生产率和质量的提高..<br /><br />Stamen says:<br />不对 Spring已经为项目带来了生产率的提高 这是用过Spring的开发人员的普遍感受&nbsp; Spring是从劳动中来到劳动中去的框架 而非EJB这种皇家血统的<br /><br />Unknow---- says:<br />是啊.你说的没错,那是国外..国内呢..你要看你周围的.而不是从网络上别人这么说哦<br /><br />Unknow---- says:<br />像EJB刚兴起的时候也是这么说的哦<br /><br />Stamen says:<br />我自己就觉得Spring让我编码轻松了不少 以前写事务代码真是太单调了<br /><br />Unknow---- says:<br />国内很多人说用SPRING为项目带来了生产率的提高,但很多都是假冒了,没有真正去思考,是不是真的带来了,这点在网上特别普遍..<br /><br />Stamen says:<br />用Spring做开发的项目是非常多的 Xxx公司这边都用Spring，我原来在yyy公司做的几个项目也是用Spring<br /><br />Unknow---- says:<br />写代码单调,这不是理由哦.&nbsp; 是要类比以前写的,是不是真的比以前写代码写的更快了..你想想以前写新增用户的事务逻辑,也就两行代码,短短的两句..而用spring呢.你要配置两行吧. <br /><br />Stamen says:<br />事务代码都不用考虑了 10分事去了2分 怎么不省事<br /><br />Unknow---- says:<br />但我问了那些yyy公司的人.有咨询过他们,他们说不错,但我问到真正的点子上的时候,却上来.都觉的跟以前比,其实真正没有带来多大的价值了<br /><br />Unknow---- says:<br />但你要配置哦..你在代码中不写,但在配置文件中要配置哦. <br /><br />Unknow---- says:<br />像小翁,张崇镇,都是在yyy公司最早使用的,也是使用的最多的..我都问过他们..<br /><br />Stamen says:<br />就象某个人 由于前列腺 一天上班要上厕所20次 现成前列腺好了 晚上回来上一次就行 难道还能不轻松吗 <br /><br />Unknow---- says:<br />但我在业务系统也可以做到只写一处就可以了..很简单.连配置文件都不用配置,如果出错了,我只看那处代码就行了..错误信息打印的都很清楚,而用配置呢,追踪BUG可能不如原始方式好吧..而且可能配置写错了,如果不太理解框架的话,还可能因为配置错了,让你找半天的BUG,这都是基于配置的缺陷.<br /><br />Stamen says:<br />那就是看配置的量和代码的量哪个大，事务要获取资源 ，做事务提供 回滚 释放资源 代码加起来没有20行恐怕搞不定，但配置有多少行，用一个parent事务&lt;bean> 事务&lt;bean>继承的方式配置，你只要为一个方法声明事务的属性就可以了，顶多1行 <br /><br />Stamen says:<br />我刚才说过 你的设计是不合理的<br /><br />Stamen says:<br />是为了达到目标不择手段的那种<br /><br />Unknow---- says:<br />代码量不大了.业务系统已经简化事务代码了...不像你说的,还要回滚处理,那太原始了. <br /><br />Stamen says:<br />你不要去问别人 自己做一个试试就OK了 当然刚开始会觉得比较麻烦 用多了就不会了 毕竟学一个东西是要代价的<br /><br />Unknow---- says:<br />这可能是我的设计理念导致的..就是设计一定要简单..如果我用这种方式,就可以做好业务系统,而且这种方式在我做过的业务系统中都很适用,为什么不采用呢,难道还要考虑像国外那么复杂的IT环境,或者考虑我的业务系统可能慢慢变成像电信银行这么大的系统吗? 我觉的这种是过度考虑需求. <br /><br />Stamen says:<br />之所以觉得不太好 我觉得很大部分原因是认识不够 还有就是固定思维<br /><br />Stamen says:<br />那我问你 如果展现不是一种方式 用C/S 有WAP，你Service能通过吗，是不是事务代码都要重写，不是多种展现 ，你哪天觉得Struts到尽头了，换个<br /><br />Stamen says:<br />Webwork ,方便吗？<br /><br />Unknow---- says:<br />webwork是一样的.. <br /><br />Stamen says:<br />如果设计不能提供这种起码的灵活性 还有设计干什么<br /><br />Unknow---- says:<br />我觉的你考虑的过度了..很多开发人员有个问题,就是过分考虑需求.. <br /><br />Unknow---- says:<br />设计都是有上下文的..&nbsp; 你觉的做业务系统,设计最主要考虑的角度是什么? 不是灵活性或者可扩展性吧..<br /><br />Stamen says:<br />好 ，先假不存在多展现和切换展现端技术的问题，你这样设计 能够允许分层开发吗？<br /><br />Unknow---- says:<br />不要片面的追求完美的设计,我觉的做业务系统最主要考虑的就是功能性和简单行.<br /><br />Unknow---- says:<br />可以允许分层开发啊.这不会为分层开发带来任何问题啊..<br /><br />Stamen says:<br />你说的这些也是要保证 ，但凡事有度<br /><br />Stamen says:<br />事务的逻辑是业务上还是展现上的？<br /><br />Unknow---- says:<br />问题我们做的架构,可以让开发人员不需要考虑事务了啊..因为底层已经都实现这种服务了<br /><br />Stamen says:<br />你的事务都是一个Action方法一个事务吗？<br /><br />Unknow---- says:<br />假如就在commonAction中实现了.开发人员继承一个action就可以获得事务服务了<br /><br />Unknow---- says:<br />是啊..<br /><br />Stamen says:<br />不跟你玩了 <br /><br />Stamen says:<br />一个Action方法一个事务，你这个大头<br /><br />Stamen is searching for:<br />我要找我笑掉的大牙了 <br />MSN Search says:<br />We couldn't find any sites containing "我要找我笑掉的大牙了 ".&nbsp;&nbsp; Try using different search words.<br /><br />Unknow---- says:<br />呵..这就是我的架构设计思路..你可以考虑下..想想我为什么这么做..而不是一定要做到思想的完美无缺性..我觉的我实践的体会就是设计一定不要考虑做到设计的完美性. <br /><br />Stamen says:<br />你也走极端了<br /><br />Unknow---- says:<br />哈....这都是来源于实践中的设计.而不是凭空捏造的.当然都有来源了.. <br /><br />Stamen says:<br />那只能说我们见过的项目多太简单了<br /><br />Unknow---- says:<br />也许吧..因为我把设计的简单化看的太重了,就是我的设计一定要保证生产率和质量的提高,我的最高设计原则就是这个.其他的不考虑. <br /><br />Stamen says:<br />我现在的项目就不允许这种粗细度<br /><br />Unknow---- says:<br />对哦..所以我就跟你说我们的环境跟国外的IT环境不一样哦..<br /><br />Unknow---- says:<br />那一天有空,你可以把你的项目说给我听听..也许我会改变我的想法.<br /><br />Stamen says:<br />我说个我现在项目的一个现实需求吧<br /><br />Unknow---- says:<br />可以啊<br /><br />Stamen says:<br />用户升级产品事务失败，将信息记录下来，并发Mail给管理员，<br />&nbsp; 这里有三个业务，升级产品事务&nbsp; 记录场景数据事务 发Mail业务 但都通过一个Action方法处理<br /><br />Unknow---- says:<br />如果记录场景数据失败,或者发email失败呢..<br /><br />Stamen says:<br />框架的简单是在能够满足业务的需求的灵活性上来做，它有一个基础 ，而不是不择手段的简化 ，否则就象60年代的大炼钢铁 有产量没有质量了。<br /><br />Unknow---- says:<br />但你要考虑国内的软件背景,一个业务系统软件究竟能用多久..不同的上下文,就有不同的设计..<br /><br />Stamen says:<br />&nbsp;&nbsp;&nbsp;&nbsp; productSerivce.upgrade(product);<br /><br />Stamen says:<br />try{<br /> productSerivce.upgrade(product);<br />}catch( RuntimeException e)<br />{<br />&nbsp;&nbsp;&nbsp; productService.recordFailLog( product);<br />&nbsp;&nbsp;&nbsp; mailSender.send( mail);<br />}<br /><br />Unknow---- says:<br />而且不是没有质量,我设计的最高原则就是软件生产率和质量的提高.. <br /><br />Unknow---- says:<br />然后呢<br /><br />Stamen says:<br /> 你上面提的小小需求你的框架都满足不了了 还说质量和生产率 质量和生产率是要做对事的前提下<br /><br />Unknow---- says:<br />错了哦..设计是依赖上下文的,老大..如果需求是这样的,当然设计要去改变了,难道一套设计就能走天下嘛.... <br /><br />Stamen says:<br />你的设计是要通用的，又不是只给一个项目用<br /><br />Stamen says:<br />给一个项目用 就直接写JSP 也是可以的<br /><br />Unknow---- says:<br />那你也极端了哦..&nbsp; 这种我的架构也是可以做的..<br /><br />Unknow---- says:<br />spring如何实现呢<br /><br />Stamen says:<br />别的先不说，有两个解决思想是一定有问题的：<br /> 1)事务在Action层控制<br />２）事务粒度为一个请求<br /><br />Unknow---- says:<br />那你说说问题的所在吧<br /><br />Stamen says:<br />上面不都说了　笨<br /><br />Unknow---- says:<br />没有吧..我怎么没发现啊.. <br /><br />Stamen says:<br />笨　笨　笨<br /><br />Unknow---- says:<br />问题还是你怎么看待action了..<br /><br />Unknow---- says:<br />那你用spring怎么解决<br /><br />Stamen says:<br />Action负责两部分的功能 ：<br />1) 页面流程控制 ，如失败转向哪儿 失败转向哪儿 等；<br />2) 业务流程控制 ，如上面我举的那个例子，成功升级后 如果处理 升级失败后 如果处理等<br /><br />Unknow---- says:<br />你说的没错了..你的那些代码应该叫做应用组织逻辑..<br /><br />Unknow---- says:<br />它不属于核心的业务逻辑..如果你把action来作为应用逻辑组成层的话.也是可以做到的<br /><br />Stamen says:<br />Action并不是完全不负责业务 ，但它控制的业务逻辑是粗粒度的 是业务流程层面上的，而非事务流程层面 <br /><br />Unknow---- says:<br />当然了..spring的基于配置事务是很用的,我在青鸟中所教的架构,就是用spring的事务,当时也提到一个spring唯一能看到实用性的价值<br /><br />Stamen says:<br />不说其实的，这一点已经很不错了<br /><br />Stamen says:<br />其他<br /><br />Stamen says:<br />你去给你们领导吹吹风吧，我到时给你们培训Spring&nbsp; <br /><br />Unknow---- says:<br />呵..就像我说的上下文一样,如果上下文不一样,设计真的不一样,就像你提的,我在北大青鸟就是用spring解决的.但不用spring也是可以解决的.<br /><br />Unknow---- says:<br />可以啊..没问题啊..不过要讲实用的.. <br /><br />Stamen says:<br />嗯 也是有一定的道理 ，不过我不相信电力的业务会那么简单<br /><br />Unknow---- says:<br />不过讲下设计思想更好了<br /><br />Unknow---- says:<br />电力业务没你想的复杂了.可能更简单.. <br /><br />Stamen says:<br />Xxx公司的开发人员水平还不太高 目前更突出的问题是开发实现上 设计思想和你聊就OK了<br /><br />Stamen says:<br />如果事务是请求级别的 那就OK<br /><br />Stamen says:<br />不过没有1K 不去讲哦 <br /><br />Unknow---- says:<br />是啊..但我是希望两个都有了,多讲下思想,对他们改变思想比较好..希望他们能听到好的思想,可以在项目中去体会..<br /><br />Unknow---- says:<br />我帮你提下..<br /><br />Unknow---- says:<br />不过不知道行不行哦.因为我以前就提过,但没成功..<br /><br />Stamen says:<br />不要紧 可以随便说 我不一定有空<br /><br />Stamen says:<br />想半年呆在家里 一边搞好生产 一边搞建设
          <br/><br/>
          <span style="color:red;">
            <a href="http://stamen.javaeye.com/blog/31046#comments" style="color:red;">已有 <strong>69</strong> 人发表留言，猛击-&gt;&gt;<strong>这里</strong>&lt;&lt;-参与讨论</a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/138' 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/41' target='_blank'><span style="color:red;font-weight:bold;">Windows7在微软WinHEC 2008上揭开神秘面纱</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sun, 29 Oct 2006 00:49:10 +0800</pubDate>
        <link>http://stamen.javaeye.com/blog/31046</link>
        <guid>http://stamen.javaeye.com/blog/31046</guid>
      </item>
          <item>
        <title>请教Acegi的投票策略问题</title>
        <author>stamen</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://stamen.javaeye.com">stamen</a>&nbsp;
                    链接：<a href="http://stamen.javaeye.com/blog/26711" style="color:red;">http://stamen.javaeye.com/blog/26711</a>&nbsp;
          发表时间: 2006年10月09日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          Acegi对用户的权限使用投票策略，投票的结果返回以int类型返回，分别是AccessDecisionVoter三个静态变量ACCESS_ABSTAIN,，ACCESS_DENIED和ACCESS_GRANTED，也即弃权，拒绝，同意。<br />&nbsp;&nbsp;&nbsp; <br />&nbsp;&nbsp; 在网上找到了一个资料说明三者分别的返回条件：<br /><br /><div class="quote_title">引用</div><div class="quote_div"><br />&nbsp;&nbsp;&nbsp; RoleVoter类是一个Acegi安全系统AccessDecisionVoter接口的实现。如果ConfigAttribute以ROLE_开头，RoleVoter则进行投票。如果GrantedAuthority的getAutority方法的String返回值匹配一个或多个以ROLE_开头的ConfigAttribute，则投票通过，否则不通过。如果没有以ROLE_开头的ConfigAttribute，RoleVoter则弃权。<br /></div><br />&nbsp;&nbsp; 可是看起来，不通过和弃权是一样的，不知道如何区分这两者的不同，请知道的前辈指点一下，谢谢！
          <br/><br/>
          <span style="color:red;">
            <a href="http://stamen.javaeye.com/blog/26711#comments" style="color:red;">已有 <strong>2</strong> 人发表留言，猛击-&gt;&gt;<strong>这里</strong>&lt;&lt;-参与讨论</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;">Windows7在微软WinHEC 2008上揭开神秘面纱</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/138' target='_blank'><span style="color:red;font-weight:bold;">加入阿里巴巴，发展潜力无限</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 09 Oct 2006 23:13:06 +0800</pubDate>
        <link>http://stamen.javaeye.com/blog/26711</link>
        <guid>http://stamen.javaeye.com/blog/26711</guid>
      </item>
          <item>
        <title>关于Spring属性编辑器详解</title>
        <author>stamen</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://stamen.javaeye.com">stamen</a>&nbsp;
                    链接：<a href="http://stamen.javaeye.com/blog/24660" style="color:red;">http://stamen.javaeye.com/blog/24660</a>&nbsp;
          发表时间: 2006年09月20日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          最近刚在研究Spring的编辑器，发现很有意思，刚好galaxystar起了一个这样贴，我想对PropertyEditor作一个详细的整理会对大家有益，特定启了这个新帖。<br />&nbsp;&nbsp;&nbsp; <br />&nbsp;&nbsp;&nbsp; 所谓的PropertyEditor，顾名思义，就是属性编辑器。由于Bean属性通过配置文档以字符串了方式为属性赋值，所以必须有一个“东东”负责将这个字符串转换为属性的直接对象，如属性的类型为int，那么编辑器要做的工作就是int i = Integer.parseInt("1");<br />&nbsp;&nbsp; Spring为一般的属性类型提供了默认的编辑器，BeanWrapperImpl是Spring框架中重要的类，它负责对注入的Bean进行包装化的管理，常见属性类型对应的编辑器即在该类中通过以下代码定义：<br />&nbsp; <br /><pre name="code" class="java">
private void registerDefaultEditors()
    {
        // Simple editors, without parameterization capabilities.
        // The JDK does not contain a default editor for any of these target types.
        this.defaultEditors.put(byte[].class, new ByteArrayPropertyEditor());
        this.defaultEditors.put(Class.class, new ClassEditor());
        this.defaultEditors.put(File.class, new FileEditor());
        this.defaultEditors.put(InputStream.class, new InputStreamEditor());
        this.defaultEditors.put(Locale.class, new LocaleEditor());
        this.defaultEditors.put(Properties.class, new PropertiesEditor());
        this.defaultEditors.put(Resource[].class,
                                new ResourceArrayPropertyEditor());
        this.defaultEditors.put(String[].class, new StringArrayPropertyEditor());
        this.defaultEditors.put(URL.class, new URLEditor());

        // Default instances of collection editors.
        // Can be overridden by registering custom instances of those as custom editors.
        this.defaultEditors.put(Collection.class,
                                new CustomCollectionEditor(Collection.class));
        this.defaultEditors.put(Set.class, new CustomCollectionEditor(Set.class));
        this.defaultEditors.put(SortedSet.class,
                                new CustomCollectionEditor(SortedSet.class));
        this.defaultEditors.put(List.class, new CustomCollectionEditor(List.class));

        // Default instances of character and boolean editors.
        // Can be overridden by registering custom instances of those as custom editors.
        PropertyEditor characterEditor = new CharacterEditor(false);
        PropertyEditor booleanEditor = new CustomBooleanEditor(false);

        // The JDK does not contain a default editor for char!
        this.defaultEditors.put(char.class, characterEditor);
        this.defaultEditors.put(Character.class, characterEditor);

        // Spring's CustomBooleanEditor accepts more flag values than the JDK's default editor.
        this.defaultEditors.put(boolean.class, booleanEditor);
        this.defaultEditors.put(Boolean.class, booleanEditor);

        // The JDK does not contain default editors for number wrapper types!
        // Override JDK primitive number editors with our own CustomNumberEditor.
        PropertyEditor byteEditor = new CustomNumberEditor(Byte.class, false);
        PropertyEditor shortEditor = new CustomNumberEditor(Short.class, false);
        PropertyEditor integerEditor = new CustomNumberEditor(Integer.class, false);
        PropertyEditor longEditor = new CustomNumberEditor(Long.class, false);
        PropertyEditor floatEditor = new CustomNumberEditor(Float.class, false);
        PropertyEditor doubleEditor = new CustomNumberEditor(Double.class, false);

        this.defaultEditors.put(byte.class, byteEditor);
        this.defaultEditors.put(Byte.class, byteEditor);

        this.defaultEditors.put(short.class, shortEditor);
        this.defaultEditors.put(Short.class, shortEditor);

        this.defaultEditors.put(int.class, integerEditor);
        this.defaultEditors.put(Integer.class, integerEditor);

        this.defaultEditors.put(long.class, longEditor);
        this.defaultEditors.put(Long.class, longEditor);

        this.defaultEditors.put(float.class, floatEditor);
        this.defaultEditors.put(Float.class, floatEditor);

        this.defaultEditors.put(double.class, doubleEditor);
        this.defaultEditors.put(Double.class, doubleEditor);

        this.defaultEditors.put(BigDecimal.class,
                                new CustomNumberEditor(BigDecimal.class, false));
        this.defaultEditors.put(BigInteger.class,
                                new CustomNumberEditor(BigInteger.class, false));
    }
</pre><br />&nbsp;&nbsp; 但是，并非Bean的属性都是这些常见的类型，如果你的Bean需要注入一个自定义类型的属性，而又想享受IoC的好处，那么就只得自己开干，提供一个自定义的PropertyEditor了。<br />&nbsp;&nbsp; 下面，分几个步骤来说明，定义一个自定义PropertyEditor的过程。<br />&nbsp; 1)首先，碰到的问题即是，要如何编辑自己的PropertyEditor,其实需要了解一点java.beans包的知识，在该包中，有一个java.beans.PropertyEditor的接口，它定义了一套接口方法（12个），即通过这些方法如何将一个String变成内部的一个对象，这两个方法是比较重要的：<br />&nbsp;&nbsp;&nbsp; a)setValue(Object value) 直接设置一个对象，一般不直接用该方法设置属性对象<br />&nbsp;&nbsp;&nbsp;&nbsp; b)setAsText(String text) 通过一个字符串来构造对象，一般在此方法中解析字符串，将构造一个<br />&nbsp;&nbsp;&nbsp;&nbsp; 类对象，调用setValue(Object)来完成属性对象设置操作。<br />&nbsp; <br />&nbsp; 2)实现所有的接口方法是麻烦的，java.beans.PropertyEditorSupport 适时登场，一般情况下，我们通过扩展这个方便类即可。<br /><br />&nbsp; 3)编写完后，就是在Spring配置文件中注册该属性类型编辑器的问题，Spring提供了专门的注册工具类<br />&nbsp;&nbsp; org.springframework.beans.factory.config.CustomEditorConfigurer，它负责将属性类型和<br />&nbsp;&nbsp; 属性编辑器关联起来。到时BeanFactory注入Bean的属性时，即会在注册表中查找属性类型对应的编辑器。<br /><br />&nbsp; 下面给出一个小例子，例子先作一个简单描述：<br />&nbsp; 1)Person 需要进行属性注入的Bean，有两个属性 一个是name,一个是address Address是一个类<br />&nbsp; 2)Address Person的属性类型，本身有3个属性。<br />&nbsp; 3)AddressPropertyEditor Address类型对应的属性编辑器。<br />&nbsp; <br />&nbsp; 开工：<br />&nbsp; 1.Person.java<br /> <pre name="code" class="java">
package com.stamen.propedit;

import org.apache.commons.lang.builder.ToStringBuilder;


public class Person {
	private String name;

	private Address address;


	public Address getAddress() {
		return address;
	}

	public void setAddress(Address address) {
		this.address = address;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
    public String toString() {
    	return ToStringBuilder.reflectionToString(this);
    }
 } 
</pre><br /> <br />&nbsp; 2.Address.java<br /> <pre name="code" class="java">
package com.stamen.propedit;
import org.apache.commons.lang.builder.ToStringBuilder;
public class Address {
	private String street;

	private String doorNum;

	private String postCode;

	public String getDoorNum() {
		return doorNum;
	}

	public void setDoorNum(String doorNum) {
		this.doorNum = doorNum;
	}

	public String getPostCode() {
		return postCode;
	}

	public void setPostCode(String postCode) {
		this.postCode = postCode;
	}

	public String getStreet() {
		return street;
	}

	public void setStreet(String street) {
		this.street = street;
	}
	
    public String toString() {
    	return ToStringBuilder.reflectionToString(this);
    }

}
 </pre><br />&nbsp; <br /> AddressPropertyEditor.java <br /> <pre name="code" class="java">
package com.stamen.propedit;

import java.beans.PropertyEditorSupport;
import java.util.Date;

import org.springframework.util.StringUtils;
public class AddressPropertyEditor extends PropertyEditorSupport{
	//支持的格式为 streeValue,doorNumValue,postCode
	public void setAsText(String text)
	{
		System.out.println("使用自己的编辑器。");
		if (text == null || !StringUtils.hasText(text)) {
			throw new IllegalArgumentException("老大，不能为空啊！");
		}
		else
		{
			String[] strArr = StringUtils.tokenizeToStringArray(text,",");
			Address add = new Address();
			add.setStreet(strArr[0]);
			add.setDoorNum(strArr[1]);
			add.setPostCode(strArr[2]);
			setValue(add);
		}
	}
	
    public String getAsText()
    {
    	Address add = (Address)getValue();
    	return ""+add;
    }
}
 </pre><br /><br /> 打开Spring配置文件，添上这两个配置项：<br /><pre name="code" class="java">
   &lt;bean id="customEditorConfigurer"  class="org.springframework.beans.factory.config.CustomEditorConfigurer">
   &lt;property name="customEditors">
     &lt;map>
       &lt;entry key="com.stamen.propedit.Address"> &lt;!-- 属性类型 -->
         &lt;bean class="com.stamen.propedit.AddressPropertyEditor"/> &lt;!--对应Address的编辑器 -->
       &lt;/entry>
     &lt;/map>
   &lt;/property>
 &lt;/bean>

  &lt;bean id="person" class="com.stamen.propedit.Person">
     &lt;property name="name" value="Tom"/>
     &lt;property name="address" value="朝阳区,Soho 1601,010101"/>
  &lt;/bean>
</pre><br />&nbsp;&nbsp; <br />&nbsp; 收工，刷牙，上床，睡觉。
          <br/><br/>
          <span style="color:red;">
            <a href="http://stamen.javaeye.com/blog/24660#comments" style="color:red;">已有 <strong>6</strong> 人发表留言，猛击-&gt;&gt;<strong>这里</strong>&lt;&lt;-参与讨论</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;">Windows7在微软WinHEC 2008上揭开神秘面纱</span></a></li><li><a href='/adverts/138' 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, 20 Sep 2006 00:03:28 +0800</pubDate>
        <link>http://stamen.javaeye.com/blog/24660</link>
        <guid>http://stamen.javaeye.com/blog/24660</guid>
      </item>
          <item>
        <title>谈谈Spring配置中&lt;bean&gt;的id和name属性的花拳秀腿</title>
        <author>stamen</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://stamen.javaeye.com">stamen</a>&nbsp;
                    链接：<a href="http://stamen.javaeye.com/blog/24525" style="color:red;">http://stamen.javaeye.com/blog/24525</a>&nbsp;
          发表时间: 2006年09月17日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          在BeanFactory的配置中，&lt;bean>是我们最常见的配置项，它有两个最常见的属性，即id和name，最近研究了一下，发现这两个属性还挺好玩的，特整理出来和大家一起分享。<br />&nbsp; 1.id属性命名必须满足XML的命名规范，因为id其实是XML中就做了限定的。总结起来就相当于一个Java变量的命名：不能以数字，符号打头，不能有空格，如123，?ad,"ab "等都是不规范的，Spring在初始化时就会报错，诸如：<br />&nbsp;&nbsp; <pre name="code" class="java">org.xml.sax.SAXParseException: Attribute value "?ab" of type ID must be a name.</pre>&nbsp; <br /><br />&nbsp; 2.name属性则没有这些限定，你可以使用几乎任何的名称，如?ab,123等，但不能带空格，如"a b"," abc"，，这时，虽然初始化时不会报错，但在getBean()则会报出诸如以下的错误：<br />&nbsp; <pre name="code" class="java">org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'a b' is defined</pre><br /><br />&nbsp; 3.配置文件中不允许出现两个id相同的&lt;bean>，否则在初始化时即会报错，如：<br />&nbsp; <pre name="code" class="java">org.xml.sax.SAXParseException: Attribute value "aa" of type ID must be unique within the document.</pre>&nbsp; 4.但配置文件中允许出现两个name相同的&lt;bean>，在用getBean()返回实例时，后面一个Bean被返回,应该是前面那个&lt;bean>被后面同名的&nbsp;&nbsp; &lt;bean>覆盖了。有鉴于此，为了避免不经意的同名覆盖的现象，尽量用id属性而不要用name属性。<br /><br />&nbsp; 5.name属性可以用,隔开指定多个名字，如&lt;bean name="b1,b2,b3">,相当于多个别名，这时通过getBean("a1") getBean("a2") getBean("a3")返回的都是同一个实例（假设是singleton的情况）<br />&nbsp; <br />&nbsp;&nbsp; 6.如果id和name都没有指定，则用类全名作为name，如&lt;bean class="com.stamen.BeanLifeCycleImpl">,则你可以通过<br />&nbsp;&nbsp; getBean("com.stamen.BeanLifeCycleImpl")返回该实例。<br /><br />&nbsp; 7.如果存在多个id和name都没有指定，且实例类都一样的&lt;bean>，如:<br />&nbsp;&nbsp; <pre name="code" class="java">&lt;bean class="com.stamen.BeanLifeCycleImpl"/>
   &lt;bean class="com.stamen.BeanLifeCycleImpl"/>
   &lt;bean class="com.stamen.BeanLifeCycleImpl"/></pre>&nbsp;&nbsp; 则第一个bean通过getBean("com.stamen.BeanLifeCycleImpl")获得，<br />&nbsp;&nbsp;&nbsp;&nbsp; 第二个bean通过getBean("com.stamen.BeanLifeCycleImpl#1")获得，<br />&nbsp;&nbsp;&nbsp;&nbsp; 第三个bean通过getBean("com.stamen.BeanLifeCycleImpl#2")获得，以此类推。<br />&nbsp; <br />&nbsp; <strong>[小结]</strong><br />&nbsp;&nbsp;&nbsp; 当然，这些都是奇技淫巧，不足以去实践，通过id指定唯一名称才是阳光大道，其他仅作为一笑而过的见闻罢了。
          <br/><br/>
          <span style="color:red;">
            <a href="http://stamen.javaeye.com/blog/24525#comments" style="color:red;">已有 <strong>5</strong> 人发表留言，猛击-&gt;&gt;<strong>这里</strong>&lt;&lt;-参与讨论</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/138' target='_blank'><span style="color:red;font-weight:bold;">加入阿里巴巴，发展潜力无限</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">Windows7在微软WinHEC 2008上揭开神秘面纱</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sun, 17 Sep 2006 23:28:06 +0800</pubDate>
        <link>http://stamen.javaeye.com/blog/24525</link>
        <guid>http://stamen.javaeye.com/blog/24525</guid>
      </item>
          <item>
        <title>Struts调用Spring服务类的三种方法</title>
        <author>stamen</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://stamen.javaeye.com">stamen</a>&nbsp;
                    链接：<a href="http://stamen.javaeye.com/blog/24476" style="color:red;">http://stamen.javaeye.com/blog/24476</a>&nbsp;
          发表时间: 2006年09月15日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          用SSH做了几个项目，现在总结一下Struts Action中调用Spring Service的方法，大家有好的实现，请继续补充：<br /><br />&nbsp; 1.<strong>老爸操持型</strong><br />&nbsp;&nbsp;&nbsp; 这种类型，即是在BaseAction中提供一个getBean(String beanName)的父类方法，业务Action 在需要Serivce时，调用父类的getBean()得到Object型的Service，再Cast。<br />&nbsp;&nbsp; e.g.<br /><pre name="code" class="java">  public class BaseAction extends DispatchAction
  {
     ... 
     public Object getBean(String name)
    {
        if (ctx == null)
        {
            ctx = WebApplicationContextUtils
                  .getRequiredWebApplicationContext(servlet.getServletContext());
        }
        return ctx.getBean(name);
    }
  }</pre><br /><br />&nbsp; 2.<strong>自已动手型</strong><br />&nbsp;&nbsp; 自己动手 丰衣足食，再加了自从有了IoC，所谓动手也只是衣来后的伸手和饭来后的张口。自己动手型，即是利用Spring的IoC，将IoC容器中的Service注入到Action中，当然Action需要提供注入服务有setter.<br />&nbsp;&nbsp; 如果采用这种方式，首先需要让Spring接管Struts，然后在Spring配置文件中，配置Action的注入属性。<br />&nbsp;&nbsp; 首先.在struts-config.xml将Spring引狼入室。<br /><pre name="code" class="java">&lt;plug-in className="org.springframework.web.struts.ContextLoaderPlugIn"> 
        &lt;set-property property="contextConfigLocation" 
                                  value="/WEB-INF/action-servlet.xml" 
        /> 
&lt;/plug-in> </pre><br />&nbsp; 然后，Struts再向Spring投怀送抱：<br /><pre name="code" class="java">
&lt;bean id="userService" class="com.nic.service.UserServiceImpl">
    &lt;property name="userDao">
	&lt;ref bean="userDao" />
    &lt;/property>
&lt;/bean>	
&lt;bean name="/userAction" class="com.stamen.web.UserAction">
   &lt;property name="userService" ref="userService"/>
&lt;/bean>
</pre>&nbsp;&nbsp;&nbsp; <br />&nbsp;&nbsp; 聪明的你一下就看出“/userAction ”即是com.stamen.web.UserAction在Struts中的配置名。<br />&nbsp; <br />3.<strong>朋友帮忙型</strong>&nbsp; 朋友多了好办事，凡事都自己动手总有一天会活活累死，所有Action为自己需要的Service提供setter，并且在Spring中注入，好累啊。小学生都在减负了，我们也来为Action减减负吧--提供一个专门<br />查找Serivice的ServiceLocator，负责获取所有的Service，该类为每个Service提供专门的获得方法，如：<br /><pre name="code" class="java">  public class ServiceLocator
{
    private static ApplicationContext factory = null;
    public static void init(ApplicationContext ctx)
    {    
        factory = ctx;
    }
    public static LogService getLogService()
    {
        return (LogService) ServiceLocator.getBean("logService");
    }

    public static UserService getUserService()
    {
        return (UserService) ServiceLocator.getBean("userService");
    }
    public static PieeService getPieeService()
    {
        return (PieeService) ServiceLocator.getBean("pieeService");
    }
    public static PieeGrid getPieeListService()
    {
        return (PieeGrid) ServiceLocator.getBean("pieeListService");
    }
    ...
 } </pre><br /><br />&nbsp;&nbsp;&nbsp; Action要用哪个Serivce时，直接通过ServiceLocator.getXxxService()就可以获得了，省去了<br />“老爸操持型”指定Service 名和Cast的繁琐，比在Spring中IoC来IoC去也来得省心省力。<br />&nbsp;&nbsp;&nbsp; <br />&nbsp;&nbsp; 下面做一个自己的分析小结：<br /> 1.“老爸操持型” 将serviceName分散到代码中，到时配置文件中serviceName一改，得牵一毛而动全身->维护性差；且要进行Cast转换，怎一个繁字了得。<br /> 2.“自己动手型”也不好，不但在Action中要添加get/setXxxService代码，而且还要在Struts和Spring的配置文件中做好群众的大串连工作，难道我们的配置还不够多吗？吃回香豆的，你别又跳出来啊：）<br /> 3.“朋友帮忙型”，目前，我认为是比较好的方式，ServiceLocator象一个服务周到，工作到位的房产“中介”，我们要租房子 何必满街跑啊？TMD 这个月我又交了3K房租，也不知道李大伦，李金宝之流规矩后，房价能不能降些，我想有个蜗牛的家 已经唱了好几年了--跑题了，睡觉去了：）
          <br/><br/>
          <span style="color:red;">
            <a href="http://stamen.javaeye.com/blog/24476#comments" style="color:red;">已有 <strong>13</strong> 人发表留言，猛击-&gt;&gt;<strong>这里</strong>&lt;&lt;-参与讨论</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;">Windows7在微软WinHEC 2008上揭开神秘面纱</span></a></li><li><a href='/adverts/138' target='_blank'><span style="color:red;font-weight:bold;">加入阿里巴巴，发展潜力无限</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Fri, 15 Sep 2006 23:42:29 +0800</pubDate>
        <link>http://stamen.javaeye.com/blog/24476</link>
        <guid>http://stamen.javaeye.com/blog/24476</guid>
      </item>
      </channel>
</rss>