??xml version="1.0" encoding="utf-8" standalone="yes"?>亚洲国产精品一区二区九九,亚洲av无码乱码国产精品,亚洲成a人无码av波多野按摩http://www.tkk7.com/wuxufeng8080/category/12357.html弱水三千Q只取一瓢,便能解Q佛法无边,奉行一法,便能得益?/description>zh-cnFri, 02 Dec 2011 01:32:17 GMTFri, 02 Dec 2011 01:32:17 GMT60SSH配置QHibernate的packagesToScan路径解析分析 (zt)http://www.tkk7.com/wuxufeng8080/articles/363835.html风h?/dc:creator>风h?/author>Tue, 15 Nov 2011 06:29:00 GMThttp://www.tkk7.com/wuxufeng8080/articles/363835.htmlhttp://www.tkk7.com/wuxufeng8080/comments/363835.htmlhttp://www.tkk7.com/wuxufeng8080/articles/363835.html#Feedback0http://www.tkk7.com/wuxufeng8080/comments/commentRss/363835.htmlhttp://www.tkk7.com/wuxufeng8080/services/trackbacks/363835.htmlcom.xxx.entity" />Q?会解析成"classpath*:com/xxx/entity**/*.class"Q这个\径可以找出com/xxx/entity根目录下的类文g

2. <property name="packagesToScan" value="com.xxx.entity.*" />Q?会解析成"classpath*:com/xxx/entity/***/*.class"Q这个\径可以找出com/xxx/entity根目录下一U子目录中的cLӞ如com/xxx/entity/son/Hi.class Q?span style="color: #ff0000">而不能找出com/xxx/entity目录下的cL件?/span>

3.  <property name="packagesToScan" value="com.xxx.entity." />(注意最后的? Q?会{换成"classpath*:com/xxx/entity/**/*.class"Q这个\径可以找出com/xxx/entity根目录下及其子孙目录下所有的cL? 一般来Ԍq些是我们要的文g?br />
转蝲?http://saberhaha.iteye.com/blog/772083

]]>
Spring MVC异常处理(ZT)http://www.tkk7.com/wuxufeng8080/articles/191150.html风h?/dc:creator>风h?/author>Mon, 07 Apr 2008 00:15:00 GMThttp://www.tkk7.com/wuxufeng8080/articles/191150.htmlhttp://www.tkk7.com/wuxufeng8080/comments/191150.htmlhttp://www.tkk7.com/wuxufeng8080/articles/191150.html#Feedback1http://www.tkk7.com/wuxufeng8080/comments/commentRss/191150.htmlhttp://www.tkk7.com/wuxufeng8080/services/trackbacks/191150.html 语句针对不同的异常进行相应处理?br /> 但是在具体实CQ由于异常层ơ、种cȝ杂,我们往往很难在Servlet、JSP层妥善的?br /> 理好所有异常情况,代码中大量的try/catch代码昑־ؓ凌ؕ?br /> 我们通常面对下面两个主要问题Q?br /> 1Q?对异常实现集中式处理
典型情况Q对数据库异常记录错误日志。一般处理方法无外两U,一是在各处数据?br /> 讉K代码的异常处理中Q加上日志记录语句。二是将在数据访问代码中异常向上抛
出,q在上层l构中进行集中的日志记录处理?br /> W一U处理方法失之繁琐、ƈ且导致系l难以维护,假设后需求ؓ“对于数据库异
常,需记录日志Qƈ发送通知消息告知pȝ理?#8221;。我们不得不对分散在pȝ中的?br /> 处代码进行整改,工作量庞大?br /> W二U处理方法实Cl一的异常处理,但如果缺乏设计,往往使得上层异常处理q?br /> 于复杂?br /> q里Q我们需要的是一个设计清晰、成熟可靠的集中式异常处理方案?br /> 2Q?Ҏ捕获异常的处?br /> 对于Unchecked Exception而言Q由于代码不强制捕获Q往往被程序员所忽略Q如?br /> q行期生了Unchecked ExceptionQ而代码中又没有进行相应的捕获和处理,则我
们可能不得不面对尬?00服务器内部错误提C页面?br /> q里Q我们需要一个全面而有效的异常处理机制?br /> 上面q两个问题,从技术角度上而言q算不上什么大的难炏V套用一些短q_的设计模式,
我们也能q行处理q获得不错的效果。同Ӟ目前大多数服务器也都支持在Web.xml中通过
<error-page>QWebsphere/WeblogicQ或?lt;error-code>(Tomcat)节点配置特定异常?br /> 늚昄面?br /> Spring MVC中提供了一个通用的异常处理机Ӟ它提供了一个成熟的Q简z清晰的异常?br /> 理方案。如果基于Spring MVC开发Web应用Q那么利用这套现成的机制q行异常处理也更加自
然和有效?br /> Spring MVC中的异常处理Q?br /> 以前面的注册pȝZQ首先,在Dispatcher配置文gConfig.xml中增加id?br /> “exceptionResolver”的bean定义Q?br /> <bean id="exceptionResolver"
class="org.springframework.web.servlet.handler.SimpleMappingEx
ceptionResolver">
<property name="defaultErrorView">
<value>failure</value>
</property>
<property name="exceptionMappings">
<props>
<prop key="java.sql.SQLException">showDBError</prop>
<prop key="java.lang.RuntimeException">showError</prop>
</props>
</property>
</bean>
通过SimpleMappingExceptionResolver我们可以不同的异常映射C同的jsp?br /> 面(通过exceptionMappings属性的配置Q,同时我们也可以ؓ所有的异常指定一个默认的?br /> 常提C页面(通过defaultErrorView属性的配置Q,如果所抛出的异常在exceptionMappings
中没有对应的映射Q则Spring用此默认配|显C异怿息(注意q里配置的异常显C界面均
仅包括主文g名,至于文g路径和后~已经在viewResolver中指定)?br /> 一个典型的异常昄面如下Q?br /> <html>
<head><title>Exception!</title></head>
<body>
<% Exception ex = (Exception)request.getAttribute("exception"); %>
<H2>Exception: <%= ex.getMessage();%></H2>
<P/>
<% ex.printStackTrace(new java.io.PrintWriter(out)); %>
</body>
</html>
exception 实在SimpleMappingExceptionResolver 被存攑ֈrequest中的Q具体可以查看源代码?br /> 如果SimpleMappingExceptionResolver无法满异常处理的需要,我们可以针对
HandlerExceptionResolver接口实现自己异常处理c,q同样非常简单(只需要实C?br /> resolveExceptionҎQ?br />
如果有ViewResolverQ则制定的jsp面必须在那个页面下Q到时候如果找不到面Q可以根据错误提C再调整面路径

]]>
Spring 2中autowire="byName" /"byType" http://www.tkk7.com/wuxufeng8080/articles/101859.html风h?/dc:creator>风h?/author>Mon, 05 Mar 2007 03:30:00 GMThttp://www.tkk7.com/wuxufeng8080/articles/101859.html     如果bean有两个属性,一个想默认注入Q一个想自定义,只要讑֮了autowireQ然后显式的声明那个惌定义的,可以达到要求。这应了需求,在需要特别配|的时候就提供配置Q否则给我一个默认注入?br />    q可以在栚w?lt;beans>节点写一句default-autovwrie="byName"Q可以让文g里的所有bean 都默认autowrie。不q有为开发期可以q样Q但Production Server上不应该使用Autowire。但有h认ؓ那些自定义一ơ的地方比如TranscationManager应该详细定义Q而Dao,Serviceq种大量重复定义的bean可以这样做?img src ="http://www.tkk7.com/wuxufeng8080/aggbug/101859.html" width = "1" height = "1" />

]]>
Spring2.0--单元试要点 http://www.tkk7.com/wuxufeng8080/articles/98819.html风h?/dc:creator>风h?/author>Thu, 08 Feb 2007 09:11:00 GMThttp://www.tkk7.com/wuxufeng8080/articles/98819.htmlSpring2.0 参考手册中文翻?-W??试Q浓~即_֍的更CSpringSide wiki中的--Spring下的单元试要点?

     注意Q文档还在不断修改中Q徏议直接看Wiki 上的最新版?/a>?/p>

1. 需要Spring 依赖注入的测?/h2>

   Z试Spring理下的BeanQ可以自行构造BeanFactoryQ也可以l承?span class="nobr">AbstractDependencyInjectionSpringContextTestsQ实现public String[] getConfigLocations()函数Q?q回applicationContext文g路径的数l?/p>

 protectedString[] getConfigLocations() {        returnnewString[]{"classpath*:spring/*.xml",  "classpath*:spring/test/*.xml"}; } 

  q显式写一些需要注入的变量的setter函数?/p>

    tips1Q此基类有一个applicationContext的成员变量,所以除了依靠setter注入外,q可以随时用applicationContext.getBean() 取出所需的bean。?/p>

    tips2Q注意此基类 默认是autowire by type的,所以如果context文g里有两个相同cd的Bean׃报错Q可能需要在getConfigLocations()函数里,setAutowireMode(AUTOWIRE_BY_NAME);把它讑֛by nameQ或者取消setter函数Q自行用applicationContext.getBean()来显式查找Bean?/p>

2. Dao试

AbstractTransactionalDataSourceSpringContextTests l承于AbstractDependencyInjectionSpringContextTestsQ除了拥有上cȝ能力外,q管理了每个试的事务,会在每个试后默认回滚所有的操作?/p>

深层解释Q此cȝ实现其实依赖于Application Context中定义的 PlatformTransactionManager。由于用了Autowrie by typeQ可以Q意取名?/p>

         另依赖于Application Context中定义的DataSourceQ同样可以Q意取名?/tt> 

tips1Q如果需要在试后提交,需要setRollBack(false); 或者调用setComplete()

tips2Q此基类q通过注入的DataSource创徏了一个JDBCTemplate 变量Q可以跑SQL帮忙核对Hibernate的结果,Spring确保该查询在同一个事务内执行。ؓ正常工作你需要告诉你的ORM工具'h'它的已改变内容,例如使用Hibernate Session 接口?flush() Ҏ?/p>

tips3Q除了tips2以外Q还有countRowsInTable(String tableName)QdeleteFromTables(String[] names) QexecuteSqlScript(String sqlResourcePath, boolean continueOnError)三个便函数?/p>

3. Controller试

Controller试一般要用MockObject 分离Service层,要copy WEB-INF/下的相关文gcopy 到classpathQ而且Controller不含太多的逻辑Q所有测试controller有点吃力不讨好,直接用Seleniumq行集成试Q见(Selenium试概述)?/p>

4.SpringSide里的试

因ؓSpring默认的基cd字较长,SpringSide 在core 的org.springside.core.test 中重新承了它们Qƈ提供了默认读取所有按springside 文g存放规则存放的context 文g的getConfigLocations()函数?/p>

默认d所有context文g的getConfigLocations()函数寚w度和测试的隔离化都有媄响,可以在子c重新实现。不q自己重C个个写相关context文g也好烦,而且其实在全lazy-load的情况下Q速度也还可以接受。如何取舍要自己q了?/p>

对于CRUD的测试,在helloworldCZ里的变量名都作了泛化Q可以快速copy到另一个测试里?/p>

另外Q留意resources/spring/test 下的文gQ利用了Spring?span class="nobr">PropertyOverrideConfigurerQ新讑֮试时的ApplicatonContext 里各个Bean的属性如指定试用的DataSourceQ详l用法见Spring配置要点?/p>

]]>
spring 中集?xfire(ZT)http://www.tkk7.com/wuxufeng8080/articles/60521.html风h?/dc:creator>风h?/author>Fri, 28 Jul 2006 03:28:00 GMThttp://www.tkk7.com/wuxufeng8080/articles/60521.html首先Q我们先创徏我们的Web服务Q采用接口和实现cȝ方式Q?br />
接口MathService.javaQ?br />
  1. package com.kuaff.xfire.samples;
  2. public interface MathService
  3. {
  4.     public long add(int p1, int p2);
  5. }


实现c:
  1. package com.kuaff.xfire.samples;
  2. public class MathServiceImpl implements MathService
  3. {
  4.     public long add(int p1, int p2)
  5.     {
  6.         return p1 + p2;
  7.     }
  8. }


META-INF/xfire/service.xml文g可以省略了,因ؓweb服务的定义在xfire-servlet.xml中可以找到?br />下面要做的工具就是配|了?br />在WEB-INF文g夹下创徏applicationContext.xml文gQ这是Spring的配|文Ӟ如果你用其他的Spring配置文gQ可以将下面的beand到那个配|文件中Q?br />

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
  3. <beans>
  4.     <bean id="mathBean" class="com.kuaff.xfire.samples.MathServiceImpl"/>
  5. </beans>


定义了mathBeanQ这个Bean是我们的实现类Q当然你也可以在q个文g中定义其他的需要Spring理的bean?br />
在WEB-INF文g夹下创徏xfire-servlet.xml文gQ根据Spring规范Q这个文件名起做xfire-servlet.xml,其中xfire是web.xml配置的DispatcherServlet的名U?

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
  3. <beans>
  4.     <bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
  5.         <property name="urlMap">
  6.             <map>
  7.                 <entry key="/MathService">
  8.                     <ref bean="math"/>
  9.                 </entry>
  10.             </map>
  11.         </property>
  12.     </bean>
  13.    
  14.     <bean id="math" class="org.codehaus.xfire.spring.remoting.XFireExporter">
  15.         <property name="serviceFactory">
  16.             <ref bean="xfire.serviceFactory"/>
  17.         </property>
  18.         <property name="xfire">
  19.             <ref bean="xfire"/>
  20.         </property>
  21.         <property name="serviceBean">
  22.             <ref bean="mathBean"/>
  23.         </property>
  24.         <property name="serviceClass">
  25.             <value>com.kuaff.xfire.samples.MathService</value>
  26.         </property>
  27.     </bean>
  28. </beans>


q个文g的上半部分将MathServiceq个URL和mathq个bean联系在一赗下半部分定义了Web服务的bean和服务接口。其中mathBean是我们在applicationContext.xml中配|的那个Bean?br />
最后一步就是修改web.xml文gQ?br />
  1. <?xml version="1.0" encoding="ISO-8859-1"?>
  2. <!DOCTYPE web-app
  3.     PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
  4.     "http://java.sun.com/dtd/web-app_2_3.dtd">
  5. <web-app>
  6.     <context-param>
  7.         <param-name>contextConfigLocation</param-name>
  8.         <param-value>/WEB-INF/applicationContext.xml
  9.         classpath:org/codehaus/xfire/spring/xfire.xml</param-value>
  10.     </context-param>
  11.     <context-param>
  12.         <param-name>log4jConfigLocation</param-name>
  13.         <param-value>/WEB-INF/log4j.properties</param-value>
  14.     </context-param>
  15.     <listener>
  16.         <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
  17.     </listener>
  18.     <listener>
  19.         <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  20.     </listener>
  21.     <servlet>
  22.         <servlet-name>xfire</servlet-name>
  23.         <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  24.     </servlet>
  25.     <servlet-mapping>
  26.         <servlet-name>xfire</servlet-name>
  27.         <url-pattern>/*</url-pattern>
  28.     </servlet-mapping>
  29. </web-app>


需要注意这个文件的三个部分Q?br />
 

1Q      在定义contextConfigLocation参数时一定要加上classpath:org/codehaus/xfire/spring/xfire.xml?br />
2Q      定义listener: org.springframework.web.context.ContextLoaderListener

3Q      定义DispatcherServlet: xfire

q样Q你可以访问http://localhost:8080/xfire/MathService来调用这个Web服务Q也可以通过|址http://localhost:8080/xfire/MathService?wsdl来查看wsdl文档?

]]>
Spring--使用quartz实现定时作业 (ZT)http://www.tkk7.com/wuxufeng8080/articles/58707.html风h?/dc:creator>风h?/author>Tue, 18 Jul 2006 02:58:00 GMThttp://www.tkk7.com/wuxufeng8080/articles/58707.html    而在Spring里,已经很好的集成了QuartzQ简单到像配cron一P在xml文g里面配一下时间就可以自动执行Q不需要写一行代码。Spring对Quartz大刀阔斧的简化堪U范例,Quartz目l也许可以学习一下?/p>
    <bean id="methodInvokingJobDetail"
        class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
        <property name="targetObject"><ref bean="financeDAO"/></property>
        <property name="targetMethod"><value>confirmOrder</value></property>
    </bean>

    <bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
        <property name="jobDetail">
            <ref bean="methodInvokingJobDetail"/>
        </property>
        <property name="cronExpression">
            <value>0 0 6,12,20 * * ?</value>
        </property>
    </bean>
    <bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
        <property name="triggers">
            <list><ref local="cronTrigger"/></list>
        </property>
    </bean>

上面q段配置文g规定了在早上6点和晚上8Ҏ行financeDAO对象的confirmOrder()Ҏ.


附:cronExpression配置说明

 

字段   允许?/th>   允许的特D字W?/th>
U?/code>   0-59   , - * /
?/code>   0-59   , - * /
  0-23   , - * /
日期   1-31   , - * ? / L W C
月䆾   1-12 或?JAN-DEC   , - * /
星期   1-7 或?SUN-SAT   , - * ? / L C #
q_可选)   留空, 1970-2099   , - * /


"Cron-Expression"与linux中的crontab有很大的不同Q昨天差点迷惑了我?
"Cron-Expression"??个用I格分开的字D늻成的表达式这6?个字D必遵循下面的序和格式:
Seconds                 0-59                             , - * /
Minutes                  0-59                             ,- * /
Hours                     0-23                             , - * /
Day-of-month         1-31                             , - * ? / L W C
Month                   1-12 or JAN-DEC         , - * /
Day-of-Week      1-7 or SUN-SAT           , - * ? / L C #
Year (Optional)     empty, 1970-2099         , - * /
*是一个通配W,表示M|用在Minutes字段中表C每分钟?br /> ?只可以用在day-of-month或者Day-of-Week字段中,用来表示不指定特D的倹{?br /> -用来表示一个范_比如10-12用在Month中表C?0?2月?br /> ,用来表示附加的|比如MON,WED,FRI在day-of-week字段中表C礼拜一和礼拜三和礼拜五?br /> /用来表示增量Q比?/15用在Minutes字段中表CZ0分开??5?0?5分?br /> L只可以用在day-of-month或者Day-of-Week字段中,如果用在Day-of-month中,表示某个月的最后一天,1月则是表C?1P2月则表示28P非闰q_Q如果用在Day-of-Week中表C礼拜六Q数?Q;但是如果L与数字组合在一L在Day-of-month中,比如6LQ则表示某个月的最后一个礼拜六Q?br /> C
W
#

0 1 0 1 1-12 ?表示每月1??分执行?br /> 0 0 21 ? * 1表示每个C拜?21?分执行?br /> 0 0 0 * * ?表示每天0?分执行?br /> 0 * 22 * * ?表示每天22点开始每分钟
0 * 0-23 * * ?表示每天每分?/div>

Cron表达式的旉字段除允许设|数值外Q还可用一些特D的字符Q提供列表、范围、通配W等功能Q细说如下:

?/span>星号(*)Q可用在所有字D中Q表C对应时间域的每一个时刻,例如Q?/span>*在分钟字D|Q表C?/span>每分?/span>Q?/span>

?/span>问号Q?/span>?Q:该字W只在日期和星期字段中用,它通常指定?/span>无意义的?/span>Q相当于点位W;

?/span>减号(-)Q表达一个范_如在时字段中?/span>“10-12”Q则表示?/span>10?/span>12点,?/span>10,11,12Q?/span>

?/span>逗号(,)Q表达一个列表|如在星期字段中?/span>“MON,WED,FRI”Q则表示星期一Q星期三和星期五Q?/span>

?/span>斜杠(/)Q?/span>x/y表达一个等步长序列Q?/span>xv始|y为增量步长倹{如在分钟字D中使用0/15Q则表示?/span>0,15,30?/span>45U,?/span>5/15在分钟字D中表示5,20,35,50Q你也可以?/span>*/yQ它{同?/span>0/yQ?/span>

?/span>LQ该字符只在日期和星期字D中使用Q代?/span>“Last”的意思,但它在两个字D中意思不同?/span>L在日期字D中Q表C个月份的最后一天,如一月的31P非闰q二月的28P如果L用在星期中,则表C星期六Q等同于7。但是,如果L出现在星期字D里Q而且在前面有一个数?/span>XQ则表示q个月的最?/span>X?/span>Q例如,6L表示该月的最后星期五Q?/span>

?/span>WQ该字符只能出现在日期字D里Q是对前导日期的修饰Q表C离该日期最q的工作日。例?/span>15W表示该?/span>15hq的工作日,如果该月15h星期六,则匹?/span>14h期五Q如?/span>15日是星期日,则匹?/span>16h期一Q如?/span>15h星期二,那结果就?/span>15h期二。但必须注意兌的匹配日期不能够跨月Q如你指?/span>1WQ如?/span>1h星期六,l果匚w的是3h期一Q而非上个月最后的那天?/span>W字符串只能指定单一日期Q而不能指定日期范_

?/span>LWl合Q在日期字段可以l合使用LWQ它的意思是当月的最后一个工作日Q?/span>

?/span>井号(#)Q该字符只能在星期字D中使用Q表C当月某个工作日。如6#3表示当月的第三个星期?/span>(6表示星期五,#3表示当前的第三个)Q?/span>4#5表示当月的第五个星期三,假设当月没有W五个星期三Q忽略不触发Q?/span>

?/span> CQ该字符只在日期和星期字D中使用Q代?/span>“Calendar”的意思。它的意思是计划所兌的日期,如果日期没有被关联,则相当于日历中所有日期。例?/span>5C在日期字D中q当于日历5日以后的W一天?/span>1C在星期字D中相当于星期日后的W一天?/span>Cron表达式对Ҏ字符的大写不敏感,对代表星期的~写英文大小写也不敏感。表2下面l出一些完整的Cron表示式的实例Q?/span>

?/span>2 Cron表示式示?/span>

表示?/span>

说明

"0 0 12 * * ? "

每天12点运?/span>

"0 15 10 ? * *"

每天10:15q行

"0 15 10 * * ?"

每天10:15q行

"0 15 10 * * ? *"

每天10:15q行

"0 15 10 * * ? 2008"

?/span>2008q的每天10Q?/span>15q行

"0 * 14 * * ?"

每天14点到15点之间每分钟q行一ơ,开始于14:00Q结束于14:59?/span>

"0 0/5 14 * * ?"

每天14点到15Ҏ5分钟q行一ơ,开始于14:00Q结束于14:55?/span>

"0 0/5 14,18 * * ?"

每天14点到15Ҏ5分钟q行一ơ,此外每天18点到19Ҏ5钟也q行一ơ?/span>

"0 0-5 14 * * ?"

每天14:00点到14:05Q每分钟q行一ơ?/span>

"0 10,44 14 ? 3 WED"

3月每周三?/span>14:10分到14:44Q每分钟q行一ơ?/span>

"0 15 10 ? * MON-FRI"

每周一Q二Q三Q四Q五?/span>10:15分运行?/span>

"0 15 10 15 * ?"

每月15?/span>10:15分运行?/span>

"0 15 10 L * ?"

每月最后一?/span>10:15分运行?/span>

"0 15 10 ? * 6L"

每月最后一个星期五10:15分运行?/span>

"0 15 10 ? * 6L 2007-2009"

?/span>2007,2008,2009q每个月的最后一个星期五?/span>10:15分运行?/span>

"0 15 10 ? * 6#3"

每月W三个星期五?/span>10:15分运行?/span>



]]>在Spring集成XFirehttp://www.tkk7.com/wuxufeng8080/articles/56374.html风h?/dc:creator>风h?/author>Mon, 03 Jul 2006 08:42:00 GMThttp://www.tkk7.com/wuxufeng8080/articles/56374.html

XFire可以很好的集成到Spring中,Spring的代码已l做了这斚w的集成?br />首先Q我们先创徏我们的Web服务Q采用接口和实现cȝ方式Q?br />
接口MathService.javaQ?br />
package com.kuaff.xfire.samples;



public interface MathService

{

  public long add(int p1, int p2);

}


实现c:

package com.kuaff.xfire.samples;



public class MathServiceImpl implements MathService

{

  public long add(int p1, int p2)

  {

    return p1 + p2;

  }

}


META-INF/xfire/service.xml文g可以省略了,因ؓweb服务的定义在xfire-servlet.xml中可以找到?br />下面要做的工具就是配|了?br />在WEB-INF文g夹下创徏applicationContext.xml文gQ这是Spring的配|文Ӟ如果你用其他的Spring配置文gQ可以将下面的beand到那个配|文件中Q?br />


<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">

<beans>

  <bean id="mathBean" class="com.kuaff.xfire.samples.MathServiceImpl"/>

</beans>


定义了mathBeanQ这个Bean是我们的实现类Q当然你也可以在q个文g中定义其他的需要Spring理的bean?br />
在WEB-INF文g夹下创徏xfire-servlet.xml文gQ根据Spring规范Q这个文件名起做xfire-servlet.xml,其中xfire是web.xml配置的DispatcherServlet的名U?


<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">

<beans>

  <bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">

    <property name="urlMap">

        <map>

          <entry key="/MathService">

            <ref bean="math"/>

          </entry>

        </map>

    </property>

  </bean>

 

  <bean id="math" class="org.codehaus.xfire.spring.remoting.XFireExporter">

    <property name="serviceFactory">

        <ref bean="xfire.serviceFactory"/>

    </property>

    <property name="xfire">

        <ref bean="xfire"/>

    </property>

    <property name="serviceBean">

        <ref bean="mathBean"/>

    </property>

    <property name="serviceClass">

        <value>com.kuaff.xfire.samples.MathService</value>

    </property>

  </bean>

</beans>


q个文g的上半部分将MathServiceq个URL和mathq个bean联系在一赗下半部分定义了Web服务的bean和服务接口。其中mathBean是我们在applicationContext.xml中配|的那个Bean?br />
最后一步就是修改web.xml文gQ?br />
<?xml version="1.0" encoding="ISO-8859-1"?>



<!DOCTYPE web-app

  PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"

  "http://java.sun.com/dtd/web-app_2_3.dtd">

<web-app>

  <context-param>

    <param-name>contextConfigLocation</param-name>

    <param-value>/WEB-INF/applicationContext.xml

    classpath:org/codehaus/xfire/spring/xfire.xml</param-value>

  </context-param>



  <context-param>

    <param-name>log4jConfigLocation</param-name>

    <param-value>/WEB-INF/log4j.properties</param-value>

  </context-param>



  <listener>

    <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>

  </listener>



  <listener>

    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>

  </listener>



  <servlet>

    <servlet-name>xfire</servlet-name>

    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>

  </servlet>



  <servlet-mapping>

    <servlet-name>xfire</servlet-name>

    <url-pattern>/*</url-pattern>

  </servlet-mapping>

</web-app>


需要注意这个文件的三个部分Q?br />


1Q?    在定义contextConfigLocation参数时一定要加上classpath:org/codehaus/xfire/spring/xfire.xml?br />
2Q?    定义listener: org.springframework.web.context.ContextLoaderListener

3Q?    定义DispatcherServlet: xfire

q样Q你可以访?a href="http://localhost:8080/xfire/MathService" target="_blank">http://localhost:8080/xfire/MathService来调用这个Web服务Q也可以通过|址http://localhost:8080/xfire/MathService?wsdl来查看wsdl文档?/span>


]]>
Spring Framework标记库初学者指?/title><link>http://www.tkk7.com/wuxufeng8080/articles/54210.html</link><dc:creator>风h?/dc:creator><author>风h?/author><pubDate>Wed, 21 Jun 2006 05:38:00 GMT</pubDate><guid>http://www.tkk7.com/wuxufeng8080/articles/54210.html</guid><wfw:comment>http://www.tkk7.com/wuxufeng8080/comments/54210.html</wfw:comment><comments>http://www.tkk7.com/wuxufeng8080/articles/54210.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/wuxufeng8080/comments/commentRss/54210.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/wuxufeng8080/services/trackbacks/54210.html</trackback:ping><description><![CDATA[ <h3>Spring架构要介l:</h3> <br />    Spring是一个服务于所有层面的application framework:提供了bean的配|基QAOP的支持,JDBC的提取框?抽象事务支持Q等{。它有一个非常显著的特点Q在某个层面上如果你不需要Spring的支持,你就可以不用String的classQ只使用它的某一部分的功能。从它的设计理念Q你可以看到String帮助你实C真正的逻辑层和web层的分离?br />   相对于EJB来说QSpring是一个轻量的J2EE应用开发框架。这里提到的轻量U指的是Spring框架本nQ而不是说Spring只能适用于轻量的应用开发。Spring的轻盈体现在其框架本w的基础l构以及对其他应用工L支持和装配能力,与EJBq种庞然大物相比QSpring使我们把各个技术层ơ之间的风险降低。EJB的内聚性较强,比如数据持久层管理、事务管理、生命周期管理都全部交给了EJB容器中管理,内聚性的白盒特征使我们必L弃一部分可控性而去信Q容器能力。而Spring则是考虑如何“不造轮子”,如何更好的组装这些轮子,让他们更好的转动。比如数据持久层理可以使用hibernateQ日志管理可以用jakartacommonlogging。一个比较恰当的比喻是“我们要钉几个钉子,Z完成q个目的Q锤子生产商生了大大小一pd的锤子,每个锤子都有一套复杂的使用ҎQ用来钉某种特别的钉子,l果令我们头g堪。解决锤子过多的问题Q通过springQ我们可以用几U锤子,但用h象是只有一个锤子”?注:q段话是在网上看见的Q这里引用这个比喻,我个得很生动)关于q个框架也有一些简单的ȝQ“Spring有几个主要的部分QBean+ApplicationContextQ以一U统一的、IoC的方式查找、管理、组装、用系l的lgQ取代一切工厂;持久化框Ӟweb框架。“J2EE框架”是RodJohnson的愿景,他希望Spring为J2EE轻量U解x案提供自底至的全面基础设施支持。”?br />   好了Q上面是关于一个新的Framework的简单介l,据说是未来J2EE发展的方向。以前在论坛上有关于J2EE最佳组合的讨论Q听说这个JSTL+Struts(或webwork)+Spring+Hibernate的组合很被看好(观点不一Q仅供参考,呵呵Q?如果你感兴趣的话Q可以到SpringFramework中文论坛上看看。下面{入本文的正题?br /><br /><h3>Spring 标记库介l及用法Q?/h3><br />    本文重点介lSpring 提供的标记库及其用法Q?br />当你在项目中用Spring Framework的时候,表现层可以选择Spring Framework自带的标记库。当Ӟq不是你唯一的选择。你可以选择其它标记库或模板替换技术。Spring Framework q没有ؓ应用提供非常丰富的标记库。Spring Framework 提供的标记库仅仅是ؓ了够用就行,它ƈ不是无所不包的。呵呵,q点与Struts丰富的标记库不一栗其实这点符合RodJohnson的出发点Q既“不造轮子”。当ӞSpring Framework标记库有它自w的特点Q可以说是个有益的补充吧?br /><b>Spring 标记库分cd下:</b><br />1。spring:hasBindErrors <br />2。spring:bind <br />3。spring:transform <br />4。spring:message <br />5。spring:htmlEscape <br />6。spring:theme <br /><b>下面我们来具体介l一下用法:</b><br />1?b>spring:hasBindErrors </b><br />对应org.springframework.web.servlet.tags.BindErrorsTag标记库处理类?br />q个标记提供用于l定对象的errorsQ如果这个标记被用到的话Q那么关于这个对象的错误在面上显C出来。用这个标记的前提条g是要先?lt;spring:bind>标记,q且<spring:hasBindErrors>q个标记不能用来表示对象的状态,它仅仅可以绑定对象本w和对象的属性。 具体用法如下:<br /><div id="xvnxlv9" class="codeStyle"><ol><li><spring:hasBindErrors name=<font color="#ff33ff">"priceIncrease"</font>> </li><li>    <b>Please fix all errors!</b> </li><li>  </spring:hasBindErrors> </li></ol></div><br />  通过q个单的例子Q我来具体说一下这个标记的属性吧?br />  nameQ是要被查的Bean的名字。这个属性是必需要的?br />  呵呵Q这里是单用法,所以就不介l它包含的errors变量了。具体看p文档。下同?br />  <br />2?b>spring:bind </b><br />对应org.springframework.web.servlet.tags.BindTag标记库处理类<br />q个标记用来为某个bean或bean 的属性赋|通常和form一LQ相当于action的作用。它指明表单要提交到那个cLcȝ属性中厅R?br />其中path属性是必须的,指明转到的类的\径。D例如下:<br /><div id="91npnzv" class="codeStyle"><ol><li><form method=<font color="#ff33ff">"post"</font>> </li><li>  <table width=<font color="#ff33ff">"95%"</font> bgcolor=<font color="#ff33ff">"f8f8ff"</font> border=<font color="#ff33ff">"0"</font> cellspacing=<font color="#ff33ff">"0"</font> cellpadding=<font color="#ff33ff">"5"</font>> </li><li>    <tr> </li><li>      <td alignment=<font color="#ff33ff">"right"</font> width=<font color="#ff33ff">"20%"</font>>Increase (%):</td> </li><li>      <spring:bind path=<font color="#ff33ff">"priceIncrease.percentage"</font>> </li><li>        <td width=<font color="#ff33ff">"20%"</font>> </li><li>          <input type=<font color="#ff33ff">"text"</font> name=<font color="#ff33ff">"percentage"</font> value=<font color="#ff33ff">"<c:out value="</font>${status.value}<font color="#ff33ff">"/>"</font>> </li><li>        </td> </li><li>        <td width=<font color="#ff33ff">"60%"</font>> </li><li>          <font color=<font color="#ff33ff">"red"</font>><c:out value=<font color="#ff33ff">"${status.errorMessage}"</font>/></font> </li><li>        </td> </li><li>      </spring:bind> </li><li>    </tr> </li><li>  </table> </li><li>  <br> </li><li> ……………………省? </li><li></form> </li></ol></div><br />3?b>spring:transform </b><br />对应org.springframework.web.servlet.tags.TransformTag标记库处理类,q个标记用来转换表单中不与bean中的属性一一对应的那些属性,通常?lt;spring:bind>一起用?lt;spring:transform>标记?lt;spring:bind>使用提供了更好的支持?br />属性如下:<br />valueQ必需要的。和当前<spring:bind>标记指向的beancȝ同。就是你要{换的实体cd?br />varQ不是必需的。这个字W串被用来绑定输出结果到pageQrequest, session或application scope.默认情况输出到jsp中?br />scopeQ不是必需的。前提条件var必须讄的情况下。它的值可以是pageQrequest, session或application?br /><br />4?b>spring:message </b>对应org.springframework.web.servlet.tags.MessageTag标记库处理类<br />q个标记用来帮助springframework支持国际化。和JSTL的fmt:message标记cM。当然这个标记可以很好的工作的本地的springframework框架下?br />属性如下:<br />codeQ不是必需的。用来查找message,如果没有被用的话,text被使用?br />textQ不是必需的。假如code不存在的话,默认是text输出。当code和text都没有设|的话,标记输Zؓnull.<br />varQ不是必需的。这个字W串被用来绑定输出结果到pageQrequest, session或application scope.默认情况输出到jsp中?br />scopeQ不是必需的。前提条件var必须讄的情况下。它的值可以是pageQrequest, session或application?br /><br />5?b>spring:htmlEscape </b><br />对应org.springframework.web.servlet.tags.HtmlEscapeTag标记库处理类<br />不常用,q里省略<br />6?b>spring:theme </b><br />对应org.springframework.web.servlet.tags.ThemeTag标记库处理类<br />不常用,q里省略<br />哈哈Q学习完q些用法后,让我们来看个<b>具体的例?/b>吧?br />配置步骤如下Q?br /><b>目录l构图:</b><br />-spirngapp <br />  -WEB-INF <br />      -classes <br />      -lib <br />  -src <br />  -war<br /><b>1?/b>spring.tld拯到WEB-INF目录?br /><b>2?/b>spring.jar拯到WEB-INF\lib包下<br />举例如下Q?br />在web.xml中配|好taglib属性,代码如下Q?br /><div id="brtv97z" class="codeStyle"><ol><li><?xml version=<font color="#ff33ff">"1.0"</font> encoding=<font color="#ff33ff">"UTF-8"</font>?> </li><li><!DOCTYPE web-app PUBLIC '-<i><font color="#339900">//Sun Microsystems, Inc.//DTD Web Application 2.3//EN' 'http://java.sun.com/dtd/web-app_2_3.dtd'></font></i></li><li></li><li><web-app> </li><li></li><li>  <servlet> </li><li>    <servlet-name>springapp</servlet-name> </li><li>    <servlet-<b><font color="#0000ff">class</font></b>>org.springframework.web.servlet.DispatcherServlet</servlet-<b><font color="#0000ff">class</font></b>> </li><li>    <load-on-startup>1</load-on-startup> </li><li>  </servlet> </li><li></li><li>  <servlet-mapping> </li><li>    <servlet-name>springapp</servlet-name> </li><li>    <url-pattern>*.htm</url-pattern> </li><li>  </servlet-mapping> </li><li></li><li>  <welcome-file-list> </li><li>    <welcome-file> </li><li>      index.jsp </li><li>    </welcome-file> </li><li>  </welcome-file-list> </li><li></li><li>  <taglib> </li><li>    <taglib-uri>/spring</taglib-uri> </li><li>    <taglib-location>/WEB-INFspring.tld</taglib-location> </li><li>  </taglib> </li><li></li><li></web-app> </li></ol></div><br />jsp面代码如下Q?br /><div id="pjj3fdl" class="codeStyle"><ol><li><%@ include file=<font color="#ff33ff">"/WEB-INF/jsp/include.jsp"</font> %> </li><li><%@ taglib prefix=<font color="#ff33ff">"spring"</font> uri=<font color="#ff33ff">"/spring"</font> %> </li><li></li><li><html> </li><li><head><title><fmt:message key=<font color="#ff33ff">"title"</font>/></title></head> </li><li><body> </li><li><h1><fmt:message key=<font color="#ff33ff">"priceincrease.heading"</font>/></h1> </li><li><form method=<font color="#ff33ff">"post"</font>> </li><li>  <table width=<font color="#ff33ff">"95%"</font> bgcolor=<font color="#ff33ff">"f8f8ff"</font> border=<font color="#ff33ff">"0"</font> cellspacing=<font color="#ff33ff">"0"</font> cellpadding=<font color="#ff33ff">"5"</font>> </li><li>    <tr> </li><li>      <td alignment=<font color="#ff33ff">"right"</font> width=<font color="#ff33ff">"20%"</font>>Increase (%):</td> </li><li>      <spring:bind path=<font color="#ff33ff">"priceIncrease.percentage"</font>> </li><li>        <td width=<font color="#ff33ff">"20%"</font>> </li><li>          <input type=<font color="#ff33ff">"text"</font> name=<font color="#ff33ff">"percentage"</font> value=<font color="#ff33ff">"<c:out value="</font>${status.value}<font color="#ff33ff">"/>"</font>> </li><li>        </td> </li><li>        <td width=<font color="#ff33ff">"60%"</font>> </li><li>          <font color=<font color="#ff33ff">"red"</font>><c:out value=<font color="#ff33ff">"${status.errorMessage}"</font>/></font> </li><li>        </td> </li><li>      </spring:bind> </li><li>    </tr> </li><li>  </table> </li><li>  <br> </li><li>  <spring:hasBindErrors name=<font color="#ff33ff">"priceIncrease"</font>> </li><li>    <b>Please fix all errors!</b> </li><li>  </spring:hasBindErrors> </li><li>  <br><br> </li><li>  <input type=<font color="#ff33ff">"submit"</font> alignment=<font color="#ff33ff">"center"</font> value=<font color="#ff33ff">"Execute"</font>> </li><li></form> </li><li><a href=<font color="#ff33ff">"<c:url value="</font>hello.htm<font color="#ff33ff">"/>"</font>>Home</a> </li><li></body> </li><li></html> </li></ol></div><br /><spring:bind>标记l常用来l定<input>表单元素以便提交lPriceIncrease.java,其实PriceIncrease.java中就是包含一些getter和setter的方法的cR当用户按下按钮提交的时候,其表单中的值实际上pframework攑ֈ了PriceIncrease.java中?lt;spring:bind>l常和form一起?q个${status.errorMessage}?{status.value}是一个framework定义的特D变量,它们被用来显C错误信息和当前表单中的数据。呵呵,今天到此ؓ止吧Q关于Spring Framework标记库的详细用法Q请参考其文档?br />参考资料:<br />http://www.springframework.org/<br />Spring Framework英文文档<br />Spring Framework中文论坛 <br /><img src ="http://www.tkk7.com/wuxufeng8080/aggbug/54210.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/wuxufeng8080/" target="_blank">风h?/a> 2006-06-21 13:38 <a href="http://www.tkk7.com/wuxufeng8080/articles/54210.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>spring入门~程问题集锦http://www.tkk7.com/wuxufeng8080/articles/54182.html风h?/dc:creator>风h?/author>Wed, 21 Jun 2006 04:42:00 GMThttp://www.tkk7.com/wuxufeng8080/articles/54182.htmlhttp://www.tkk7.com/wuxufeng8080/comments/54182.htmlhttp://www.tkk7.com/wuxufeng8080/articles/54182.html#Feedback0http://www.tkk7.com/wuxufeng8080/comments/commentRss/54182.htmlhttp://www.tkk7.com/wuxufeng8080/services/trackbacks/54182.html你可以通过下列途径学习springQ?
(1) spring下蝲包中doc目录下的MVC-step-by-step和sample目录下的例子都是比较好的spring开发的例子?

(2) AppFuse集成了目前最行的几个开源轻量框架或者工具Ant,XDoclet,Spring,Hibernate(iBATIS),JUnit,Cactus,StrutsTestCase,Canoo's WebTest,Struts Menu,Display Tag Library,OSCache,JSTL,Struts ?
你可以通过AppFuse源代码来学习spring?
AppFuse|站Qhttp://raibledesigns.com/wiki/Wiki.jsp?page=AppFuse

(3)Spring 开发指?夏昕)Qhttp://www.xiaxin.net/Spring_Dev_Guide.rarQ?
一本spring的入门书c?里面介绍了反转控制和依赖注射的概念,以及spring的bean理Qspring的MVCQspring和hibernteQiBatis的结合?

(4) spring学习的中文论?
SpringFramework中文论坛(http://spring.jactiongroup.net)
Java视线论坛(http://forum.javaeye.com)的spring栏目

2、利用Spring框架~程Qconsole打印出log4j:WARN Please initialize the log4j system properlyQ?
说明你的log4j.properties没有配置。请把log4j.properties攑ֈ工程的classpath中,eclipse的classpath为bin目录Q由于编译后src目录下的文g会拷贝到bin目录下,所以你可以把log4j.properties攑ֈsrc目录下?
q里l出一个log4j.properties的例子:

log4j.rootLogger=DEBUG,stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %5p (%F:%L) - %m%n


3、出?java.lang.NoClassDefFoundError?
一般情况下是由于你没有把必要的jar包放到lib中?

比如你要采用spring和hibernateQ带事务支持的话Q,你除了spring.jar外还需要hibernat.jar、aopalliance.jar、cglig.jar、jakarta-commons下的几个jar包?

http://www.springframework.org/download.html下蝲spring开发包Q提供两Uzip?/font>
spring-framework-1.1.3-with-dependencies.zip和spring-framework-1.1.3.zipQ我你下载spring-framework-1.1.3-with-dependencies.zip。这个zip解压~后比后者多一个lib目录Q其中有hibernate、j2ee、dom4j、aopalliance、jakarta-commons{常用包?


4、java.io.FileNotFoundException: Could not open class path resource [....hbm.xml],提示找不到xml文gQ?
原因一般有两个Q?
(1)该xml文g没有在classpath中?
(2)applicationContext-hibernate.xml中的xml名字没有带包名。比如:
<bean id="sessionFactory" class="org.springframework.orm.hibernate.LocalSessionFactoryBean">
<property name="dataSource"><ref bean="dataSource"/></property>
<property name="mappingResources">
<list>
<value>User.hbm.xml</value> 错,改ؓQ?<value>com/yz/spring/domain/User.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect"> net.sf.hibernate.dialect.MySQLDialect </prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
</bean>


5、org.springframework.beans.NotWritablePropertyException: Invalid property 'postDao' of bean classQ?
出现异常的原因是在application-xxx.xml中property name的错误?
<property name="...."> 中name的名字是与bean的setҎ相关的,而且要注意大写?
比如
public class PostManageImpl extends BaseManage implements PostManage {
private PostDAO dao = null;
public void setPostDAO(PostDAO postDAO){
this.dao = postDAO;
}
}
那么xml的定义应该是Q?
<bean id="postManage" parent="txProxyTemplate">
<property name="target">
<bean class="com.yz.spring.service.implement.PostManageImpl">
<property name="postDAO"><ref bean="postDAO"/></property> ?
<property name="dao"><ref bean="postDAO"/></property> ?
</bean>
</property>
</bean>


6、Spring中如何实C务管理?
首先Q如果用mysqlQ确定mysql为InnoDBcd?
事务理的控制应该放到商业逻辑层。你可以写个处理商业逻辑的JavaBeanQ在该JavaBean中调用DAOQ然后把该Bean的方法纳入spring的事务管理?

比如Qxml文g定义如下Q?
<bean id="txProxyTemplate" abstract="true"
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager"><ref bean="transactionManager"/></property>
<property name="transactionAttributes">
<props>
<prop key="save*">PROPAGATION_REQUIRED</prop>
<prop key="remove*">PROPAGATION_REQUIRED</prop>
<prop key="*">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>

<bean id="userManage" parent="txProxyTemplate">
<property name="target">
<bean class="com.yz.spring.service.implement.UserManageImpl">
<property name="userDAO"><ref bean="userDAO"/></property>
</bean>
</property>
</bean>

com.yz.spring.service.implement.UserManageImpl是我们的实现商业逻辑的JavaBean。我们通过parent元素声明其事务支持?


7、如何管理Spring框架下更多的JavaBeanQ?
JavaBean多Qspring配置文gp大,q样不易l护。ؓ了配置清晰Q我们可以将JavaBean分类理Q放在不同的配置文g中?应用启动时将所有的xml同时加蝲?
比如Q?
DAO层的JavaBean攑ֈapplicationContext-hibernate.xml中,商业逻辑层的JavaBean攑ֈapplicationContext-service.xml中。然后启动类中调用以下代码蝲入所有的ApplicationContext?

String[] paths = {"com/yz/spring/dao/hibernate/applicationContext-hibernate.xml",
"com/yz/spring/service/applicationContext-service.xml"};
ctx = new ClassPathXmlApplicationContext(paths);


8、web应用中如何加载ApplicationContextQ?
可以通过定义web.xmlQ由web容器自动加蝲?

<servlet>
<servlet-name>context</servlet-name>
<servlet-class>org.springframework.web.context.ContextLoaderServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>

<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext-hibernate.xml</param-value>
<param-value>/WEB-INF/applicationContext-service.xml</param-value>
</context-param>

9、在spring中如何配|的log4j?
在web.xml中加入以下代码即可?
<context-param>
<param-name>log4jConfigLocation</param-name>
<param-value>/WEB-INF/log4j.properties</param-value>
</context-param>


10、Spring框架入门的编E问题解决了Q我该如何更深地领会Spring框架呢?
q两本书你该ȝ看。这两本书是由Spring的作者Rod Johnson~写的?
Expert One on one J2EE Design and Development
Expert One on one J2EE Development Without EJB
你也该看看martinfowler的Inversion of Control Containers and the Dependency Injection pattern?
http://www.martinfowler.com/articles/injection.html

再好好研M下spring的文档?
http://www.jactiongroup.net/reference/html/index.htmlQ中文版Q未全部译Q?/font>

q有是多实践吧?img src ="http://www.tkk7.com/wuxufeng8080/aggbug/54182.html" width = "1" height = "1" />

]]>
使用spring-mockq行dao集成试http://www.tkk7.com/wuxufeng8080/articles/54181.html风h?/dc:creator>风h?/author>Wed, 21 Jun 2006 04:41:00 GMThttp://www.tkk7.com/wuxufeng8080/articles/54181.htmlhttp://www.tkk7.com/wuxufeng8080/comments/54181.htmlhttp://www.tkk7.com/wuxufeng8080/articles/54181.html#Feedback0http://www.tkk7.com/wuxufeng8080/comments/commentRss/54181.htmlhttp://www.tkk7.com/wuxufeng8080/services/trackbacks/54181.html在进行dao的集成测试时候,数据清理Q察看数据都是比较麻烦的事情Q用Spring-mock.jar可以帮助我们化着一个过E。我举一个简单的例子Q说明一下如何用spring-mock?

首先是po, hbm.xml, dao, daoimpl没什么好说的Q?
java代码: 


Customer.java :

package rst.spring.mock;

import java.io.Serializable;

/** @author Hibernate CodeGenerator */
publicclass Customer implementsSerializable{

    /** identifier field */
    privateLong id;

    /** nullable persistent field */
    privateString name;

    /** full constructor */
    public Customer(String name){
        this.name = name;
    }

    /** default constructor */
    public Customer(){
    }

    publicLong getId(){
        return this.id;
    }

    publicvoid setId(Long id){
        this.id = id;
    }

    publicString getName(){
        return this.name;
    }

    publicvoid setName(String name){
        this.name = name;
    }

}

Customer.hbm.xml :

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD//EN"
        "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">
<hibernate-mapping package="rst.spring.mock">
        <class name="Customer" table="customer">
                <id name="id" column="id" type="long" unsaved-value="null">
                        <generator class="identity"/>
                </id>
                <property name="name" column="name" type="string"/>
        </class>

</hibernate-mapping>

CustomerDAO :
/*
* Created on 2005-3-25
*/

package rst.spring.mock;

import org.springframework.dao.DataAccessException;

/**
* @author rst
*
*/

publicinterface CustomerDAO {
    publicvoid add(Customer customer)throws DataAccessException;
}

CustomerDAOImpl :

package rst.spring.mock;

import org.springframework.dao.DataAccessException;
import org.springframework.orm.hibernate.support.HibernateDaoSupport;

/**
* Class description.
*
* @author rst
*/

publicclass CustomerDAOHibernateImpl extends HibernateDaoSupport implements CustomerDAO{
   
    publicvoid add(Customer customer)throws DataAccessException{
        this.getHibernateTemplate().save(customer);
    }
}




然后试的基cSpringDAOTestCasel承自AbstractTransactionalDataSourceSpringContextTestsQ目前只有一个指定测试用xml文g位置的逻辑?
java代码: 


package rst.spring.mock;

import org.springframework.test.AbstractTransactionalDataSourceSpringContextTests;

/**
* Class description.
*
* @author rst
*/

publicabstractclass SpringDAOTestCase extends AbstractTransactionalDataSourceSpringContextTests {

  protectedString[] getConfigLocations(){
    returnnewString[]{ "test.xml" };
  }

}



接着是我们真正测试的cCustomerDAOTest.javaQ?
java代码: 


package rst.spring.mock;

/**
* Class description.
*
* @author rst
*/

publicclass CustomerDaoTest extends SpringDAOTestCase {

    private CustomerDAOHibernateImpl customerDAO;

    protectedvoid onSetUpInTransaction()throwsException{
        super.onSetUpInTransaction();
        //this.setPopulateProtectedVariables(true);
        customerDAO = (CustomerDAOHibernateImpl) this.applicationContext.getBean("customerDAO");
    }

    protectedvoid onTearDownInTransaction(){
        customerDAO = null;
    }

    publicvoid testInsert(){
        Customer customer = new Customer();
        customer.setName("javaeye");
        customerDAO.add(customer);
        String name = (String) jdbcTemplate.queryForObject("select name from customer where id=?", newObject[]{customer.getId()}, String.class);
       
        assertEquals(customer.getName(), name);
    }

}



最后看看配|文件test.xmlQ?
java代码: 


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">

<!--
  - Application context definition for Petclinic on Hibernate.
        -->
<beans>

        <!-- ========================= RESOURCE DEFINITIONS ========================= -->
 
        <!-- Configurer that replaces ${...} placeholders with values from a properties file -->
        <!-- (in this case, JDBC-related settings for the dataSource definition below) -->
        <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
                <property name="location"><value>classpath:jdbc.properties</value></property>
        </bean>

        <!-- Local DataSource that works in any environment -->
        <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
                <property name="driverClassName"><value>${jdbc.driverClassName}</value></property>
                <property name="url"><value>${jdbc.url}</value></property>
                <property name="username"><value>${jdbc.username}</value></property>
                <property name="password"><value>${jdbc.password}</value></property>
        </bean>

        <!-- Hibernate SessionFactory -->
        <bean id="sessionFactory" class="org.springframework.orm.hibernate.LocalSessionFactoryBean">
                <property name="dataSource"><ref local="dataSource"/></property>
                <property name="mappingResources">
                        <value>rst/spring/mock/Customer.hbm.xml</value>
                </property>
                <property name="hibernateProperties">
                        <props>
                                <prop key="hibernate.dialect">${hibernate.dialect}</prop>
                                <prop key="hibernate.show_sql">true</prop>
                        </props>
                </property>
        </bean>

        <!-- Transaction manager for a single Hibernate SessionFactory (alternative to JTA) -->
        <bean id="transactionManager" class="org.springframework.orm.hibernate.HibernateTransactionManager">
                <property name="sessionFactory"><ref local="sessionFactory"/></property>
        </bean>
       
        <bean id="hibernateTemplate" class="org.springframework.orm.hibernate.HibernateTemplate">
                <property name="sessionFactory"><ref local="sessionFactory"/></property>
        </bean>

        <bean id="customerDAO" class="rst.spring.mock.CustomerDAOHibernateImpl">
                <property name="hibernateTemplate"><ref local="hibernateTemplate"/></property>
        </bean>
</beans>


q个文g很简单,不要忘记transactionManager的配|,TestcM自动装配的?

q行之后Q就可以看到应有的结果,q且数据库中不会有数据污染。这个过E主要是开始一个transactionQ然后开始你的testҎQ执行dao操作Q执行sql查询验证l果Q最后无论成功失败rollback transaction?/span>

]]>
Spring MVC framework深入分析之一--M分析http://www.tkk7.com/wuxufeng8080/articles/54180.html风h?/dc:creator>风h?/author>Wed, 21 Jun 2006 04:36:00 GMThttp://www.tkk7.com/wuxufeng8080/articles/54180.htmlhttp://www.tkk7.com/wuxufeng8080/comments/54180.htmlhttp://www.tkk7.com/wuxufeng8080/articles/54180.html#Feedback0http://www.tkk7.com/wuxufeng8080/comments/commentRss/54180.htmlhttp://www.tkk7.com/wuxufeng8080/services/trackbacks/54180.html在当今的MVC framework里,gWebwork2逐渐成ؓLQ?Webwork2+SpringFramework的组合变得越来越行。这g意味着Spring自带的MVC frameworkq比Webwork2差,所以大家纷ULWebwork2来代ѝ确实,Spring的MVC framework不算是整个Spring的核心部Ӟ但它的威力却过了很多h的想象。很多h包括xiecc认ؓSpring的MVC framework是非怼U的,甚至比Webwork2更优U?
下面列D一下Spring的MVC framework在设计时做出的一些重要的军_Qƈ之和相关的MVC framework如Webwork2或strutsq行ҎQ?
一?Spring的整个MVC配置是基于IOC容器?
与struts或webwork2相比Q这是一个ms有点奇怪的军_Q看一下Spring MVC的配|文Ӟ最先看到的不是action或者formQ而是一些有着特定名字的beanQBean下面的配|是一些简单或有点复杂的属性。我们看到的是机器更Ҏ的数据结构,而不是h更容易理解的元素?
但是q恰恰是Spring的MVC强大的根源!因ؓ它的配置是Spring的核心IOC容器的配|,q意味着所有IOC容器的威力都可以在这里展玎ͼ我们可以为所Ʋؓ地对Spring MVCq行扩展和增强,我们可以完成在其它MVC framwork中很多难以想象的d。想扩展新的URL映射方式吗?要换一个themeResolver或LocalReolver的实现吗?惛_面中显C新cd的ViewQ比如说RDFQ呵呵,一个小U密Qxiecc是研I语义网的,虽然成天不务正业Q不写论文,只写八卦Q?甚至想直接在Controller里定义AOP吗?q些对Spring的MVC来说都是菜一?
我没有仔l研I过Webwork2的扩展机Ӟ我知道通过Webwork2的interceptor机制Q可以进行很多的扩展Q甚x一个简单简单的IOC容器。但不管它有多强大,提供了多扩展点。它的威力都很难和真正的IOC容器相比。而struts的plugin功能则是出名的滥Q虽然它也提供了plugin机制?
Spring采用IOC配置的另一个原因是使Spring的MVC与Spring的IOC容器的整合变得非常的Ҏ。Spring提供了与struts与webwork2的整合,但是q样整合都需要在q行间接的包装,感觉M是很自然。而且q会D一个概念多个配|,webwork2需要在Spring里配|beanQ再配置自己的xwork文g。想象一下吧Q我们的bean直接是一个controller,直接可以完成MVC的所有Q?q是多少爽的感觉?
Rod Johnson采用IOC容器来实现的另一个原因是q会减少好多开发工作量。看一下urlMapping吧,它提供的property本n是一个HashMapQ只有配|完成,我们的bean里的数据p然存在了Q哈哈,好爽吧。不用象struts那样解析XMLQ再把它的内容一一地dHashMap里?
虽然q样的配|会有点怪异Q但假如我们对Spring的IOC容器非常熟悉的话Q会发现它非常的亲切Q也非常的简单?
最后是一个简单的秘密,Spring怎么知道某个bean的配|就是urlMappingQ另一个bean的配|就是viewResolverQ其实很单,把所有的bean全部d内存里,然后通过bean的名字或cdLp了。通过名字L是单的getBeanҎQ通过cdL则用了BeanFactoryUtils.beansOfTypeIncludingAncestors的静态方法?/span>

二?Spring提供了明的Model, View概念和相应的数据l构
在Spring里有一个有的数据cd叫做ModelAndViewQ它只是单地把要昄的数据和昄的结果封装在一个类里。但是它却提供了明确的MVC概念Q尤其是model概念的强化,使程序的逻辑变得更清C?
记得以前在Struts里写E序里的时候,Z昄数据l常自己把东西放到HttpSession或HttpServletRequest里(或set到form里,虽然不太有用Q,q造成了model概念的模p,而且也导致了struts与JSP面的紧耦合。假如我们要替换成Veloctiy,得另外加一个plugin,因ؓ在velocity里数据是不需要不攑ֈrequest里的?
Webwork2里强调的是与Web framework解耦和它的command模式的简单性,因此在它的action里只有简单的get或setҎQ假如返回数据,也只是简单地q回一个String。当然这L实现有它的好处,但是它E化了model和view的概cRod Johnson认ؓWebwork2里的Action同时包含了Action和Model的职责,q样一个类的职责太多,不是一个很好的设计。当然Jason Carreira不太认同q种观点Q因为Action里的model对象完成可以delegel其它对象。但不管怎样Q这U争论的Ҏ在于Webwork2里E化了model, view甚至web的概c仁者见仁,见智,最后的l果q是看个人喜Ƣ好吧?

三?Spring的Controller是Singleton的,或者是U程不安全的
和Struts一PSpring的Controller是Singleton的,q意味着每个requestq来Q系l都会用原有的instanced理,q样D了两个结果:我们不用每次创徏ControllerQ减了对象创徏和垃圾收集的旉Q由于只有一个Controller的instanceQ当多个U程调用它的时候,它里面的instance变量不是U程安全的?
q也是Webwork2吹嘘的地方,它的每个Action都是U程安全的。因为每q来一个requestQ它创Z个Action对象。由于现代JDK垃圾攉功能的效率已l不成问题,所以这U创建完一个对象就扔掉的模式也得到了好多h的认可。Rod Johnson甚至以此Z证明J2EE提供的object pool功能是没多大价值的?
但是当h们在吹嘘U程安全怎么怎么重要的时候,我想请问有多h在多情况下需要考虑U程安全QRod Johnson在分析EJB的时候也提出q其它问题,q不是没有了EJB的线E安全魔法,世界׃灭亡的,大多数情况下Q我们根本不需要考虑U程安全的问题,也不考虑object pool。因为我们大多数情况下不需要保持instance状态?
臛_我写了那么多的struts ActionQ写了那么多的Spring ControllerQ几乎没有碰到需要在instance变量保持状态的问题。当然也许是我写的代码不够多QStruts的设计者Craig R. McClanahan曄说当时他设计struts时有两个条g不成熟:当时没有试驱动开发的概念Q当时JVM的垃圾收集性能太次。假如现在重新设计的话,他也会采用每个request生成一个新对象的设计方法,q样可以解决掉线E安全的问题了?br />
四?Spring不象Webwork2或tapestry那样去隐藏Servlet相关的元素如HttpServletRequest或HttpServletResponse
q又是一个重要的设计军_。在Webwork2里我们没有HttpServletRequest或者HttpServletResponseQ只有getter, setter或ActionContext里数据,q样的结果导致一个干净的ActionQ一个与Web完全无关的ActionQ一个可以在M环境下独立运行的bean。那么Webwork2的这样一个基于Command模式的ActionI竟l我们带来了什?我想主要有两点:
1?它我们的Action可以非常Ҏ地被试?
2?用户可以在Action里添加业务逻辑Qƈ被其它类重用?
然而仔l跟Spring比较一下,我们׃发现q两点功能所带来的好处其实ƈ不象我们惌的那么显著。Spring的ControllercM可以非常L被测试,看一下spring-mock下面的包吧,它提供的MockHttpServletRequest, MockHttpServletResponseq有其它一些类让测试Controller变得异常L。再看一下Action里的业务逻辑吧,Jason Carreira曄说我们可以尽情地在Webwork2的Action里加业务逻辑Q因为Action是不依赖于Web的。但是有多少人真正往Action里加业务逻辑的?大多Ch都会业务逻辑delegatel另一个ServicecLManagercR因为我们很清楚Q往Action里加业务逻辑会整个体系的分层架构变得不清晰Q不怎样QWeb层就是Web层,业务层就是业务层Q两者的逻辑混在一hM带来问题的。而且往Action里加业务逻辑会用这个Actioncd得庞大,Webwork2的Action是每个request都创建实例的Q尽带来的性能影响不太大,但ƈ不表C每ơ都要把业务逻辑再new出来Q业务逻辑在大多数的情况下应该是单例的?
不把request和response展现l用户当然还会带来功能上的损失,也许一般的场合Q用用webwork2提供的接口已l够了Q但有时我们必须要知道request和response才能发挥出更大的威力。比如我以前的一个项目里有一个通过递归动态生成的树状l构的页面,在jsp面上显C递归是痛苦或不可能的Q因此我用response直接write出页面,q在spring里很easyQ但在webwork里可能比较难了(偶不敢肯定,偶研I得不够深,也许高手是有办法的)?br />
五?Spring提供了不错但不够充分的interceptor机制
回头看一下strutsQ它在架构里甚至没有l我们提供hook point的机会,我们没有MZ加入自己的interceptor。我们只能通过重蝲struts的RequestProcessorcLq行一Ҏ限的扩展?
CWebwork2Q似乎interceptor一下子成了整个Framework的核心,除了Action的核心部Ӟ其它所有的东西都是interceptor。它的超强的interceptor功能使们扩展整个架构变得非常方便。有人称q种interceptor为AOPQJason Carreira则自豪地宣称q个叫做pragamtic AOP。我不认同这是AOPQ它只是单的interceptor机制。但不管如何Q它的interceptor实有强大的功能?
Spring也提供了它的interceptor机制Q它的HandlerInterceptor三个interceptorҎQpeHandle, postHandle, afterCompletion。分别对应Controller执行前,Controller执行后和page render之后。虽然大多数情况下已l够用,但是从功能上来说昄它没有Webwork2强大。从AOP的角度来看,它没有提供around interceptorQ而只有before与after interceptor。这意味着我们无法在interceptor前后保持状态,最单的情况假如我们要计一个Controller的执行时_我们必须在执行完before后把begintimeq个状态保持住Q再在after里把它调出来Q但是显然这个状态保持会是个问题Q我们不能把它放到instance变量里,因ؓinterceptor不是U程安全的。也讔R过ThreadLocal可以解决q个问题Q但是如此简单的功能要用到这LҎ来处理,昄q个Interceptor本n设计上还是有炚w题的?
六?Spring提供了MultiActionControllerQ它可以在一个类里包含多个Action
q个设计和struts的DispatchAction有点cMQ只不过提供了更灉|的机制。当我们的项目变大的时候,把功能类似的Ҏ攑ֈ同一个Action里完全值得的!Webwork2~少q样的机制。假如看一下Spring的源代码Q会发现其实实现MultiActionController的工作量相当的少Q只不过是用反射机制把解析出来的Ҏ名执行一下就完事了。其实Webwork2也完全可以提供这L机制。虽然从设计上来说确实不是很优雅Q但是它实很有用?br />
七?Spring提供了更多的选择方式
看看Spring里提供的Controller吧,它提供了好多不同的ControllercR要生成Wizard吗?要专门用于提交form的Controller?要执多个Ҏ的类?Spring提供了丰富的子类来扩展这些选择。当然我们还可以很轻村֜自己扩展q些功能?
再看看Spring的ViewResolver吧, 它提供了无数不同cd的ViewResolver。更重要的是我们自定义我们的面映射方式。看看strtusQ看看webwork2Q都会存在页面与forward name的一层间接{换,我们必须在配|文仉配置好某个字W串Q典型的是successQ对应的是那个页面。但是Spring里我们有了更大的自由度,我们可以采用webwork2的策略,也可以采用更单的{略Q如JSP文g名去掉扩展名的映方法。也许有U映方式很q稚Q但是我觉得它是非常有用的方式,即在大目里?
q有新的扩展吗?看看Spring Web Flow吧,它是SpringFramework的子目。它Z长串的基于页面流的Wizard面提供了可配置的实现方式。在Spring 1.3里,它将是SpringFramework的一部分?

八?Spring的tag
管Spring的tag数量上少得可怜,但它却是_ֿ设计的。它的目标很单:让美工可以轻村֜~辑面。因为在Spring的页面里Text仍然是TextQcheckbox仍然是CheckBoxQ而不象在struts或webwork2中的Tag。它只是用Springbind对输入内容进行了一下包装。所以尽页面显CZ码上会比Webwork2多,但这l对是有价值的?

在接下来的几章里Q我会分析一下Spring是如何让我们的Web应用不需要知道ApplicationContextp够访问IOC容器的,然后会对Spring的设计和执行q程q行单的源码分析Q然后给出几个扩展Spring MVC的方法?



]]>
心得QSpring AOP和Decorator模式http://www.tkk7.com/wuxufeng8080/articles/54001.html风h?/dc:creator>风h?/author>Tue, 20 Jun 2006 07:44:00 GMThttp://www.tkk7.com/wuxufeng8080/articles/54001.htmlhttp://www.tkk7.com/wuxufeng8080/comments/54001.htmlhttp://www.tkk7.com/wuxufeng8080/articles/54001.html#Feedback0http://www.tkk7.com/wuxufeng8080/comments/commentRss/54001.htmlhttp://www.tkk7.com/wuxufeng8080/services/trackbacks/54001.html xuesenlin http://www.jdon.com Oct 27, 2004 11:05 PM 回复此消? hspace=最q这个段旉都是忙于学习 SpringFrameworkQ那东东好样的,只是刚刚学完StrutsQHibernateQ有来了q个Q呵呵,Q感觉挺累的?br />“你怎么把这两个不相q的东西撤到一P?Q确实是q样Q?无论从他们的设计Q?br />实现Q用等斚w他们是风马牛不相及, 但本Z理解的方面看他们有点cM。况且学习要从对比中学呀Q这对初学者会有帮助于理解?br />重要声明Q本人都是用自己的语a写的Q有专业术语不对q请大家指出? - )
p设计模式 Decorator,也就是装饰模式,q还不好理解Q?在原有的东西上进行装C下便是装C。既然是装饰Q你要有M呀Q被修饰的东西)Q还要有装饰品。但是不你装饰来装饰去Q他的本质是不变的?p人带上了面具Q但他还是h。墙上打上了ҎQ但它还是墙呀。你也许觉得q是废话?但理解这点很重要(q是跟策略模式Strategy的区?Q本得这个是理解?Decorator 模式很重要的一炏V在开发中你经常要增强一个类的功能,或者是撤销一个类的某些功能,但是一个类l众多的功能q行装饰了以后,也许原来的类已经面目全非了,你往往会感到茫Ӟ其实Q你主要抓住他的MQ脑子里面时刻要知道你现在所作的工作是个主体进行打扮的工作?br />研究qJive的都知道Q?里面?Filter 是用了Decorator 设计模式Q那么在q个设计里面Q它的主体是什么? ForumMessage Q无疑是 ForumMessage 。装饰品当然是Filter 了,所以我们在作这件事情的时候始l是以ForumMessage为核心的QFilter q行装饰的时候,你千万不要忘C现在是ؓForumMessage而工作!有关于jive研究的文章,|上一大堆Q现在看看一个比较简单的 Decorator:



//比如有一个抽象构Ӟ
publicinterface Component {
void operation();
}
//一个具体构Ӟ
publicclass ConcreteComponent implements Component {
publicvoid operation() {
//Write your code here
}
}
//一个抽象装饎ͼ
publicclass Decorator implements Component {
private Component component;
//引用
?? ? ?br />
//商业ҎQ委z构g
publicvoid operation() {
component.operation();
}
}
//一个具体装饎ͼ
publicclass ConcreteDecorator extends Decorator {
/**
* 商业Ҏ
*/

publicvoid operation(){
//一些具体的装饰的代?/font>
......
super.operation();
// M
//一些具体的装饰的代?/font>
.......
}
}

......
我们主要看看Q在ConcreteDecorator 中的operation() ҎQ他的父cL委托到componentl徏来完成的Q其实它是MQ?一些装C码都会在q个ҎQ主体)执行前进行“预处理”或是执行后q行“收䏀?br />可不是,从上面很ҎqZQ抽象装C的operation() Ҏ没有在具体的装饰cMq行“全盘”覆盖,因ؓ他用了super.operation(); q样的语句。可见装饰模式中不管怎么P 你都要找到类D个的Ҏ。说明他的主体还在?q是跟策略模式Strategy的区?
说了怎么多,不知道大家有没有感觉到ConcreteDecoratorcM的operation()Ҏ跟Spring AOP 中的 InvocationHandler 接口的invoke()Ҏ有点相类是呢Q?br />我们来看看要实现 InvocationHandler 时候要重写的invoke()ҎQ?br />


public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
…………………?
result = method.invoke(originalObject, args);
…………………………?.
return result;
}


InvocationHandler.invoke Ҏ在被代理类的方法被调用之前触发。通过q个Ҏ中,我们可以在被代理cL法调用的前后q行一些处理,如上面代码中所C,InvocationHandler.invokeҎ的参C传递了当前被调用的ҎQMethodQ,以及被调用方法的参数。同Ӟ我们可以通过Method.invokeҎ调用被代理类的原始方法实现。这P我们可以在被代理类的方法调用前后大做文章。(说明Q引用了Spring 开发指南中的一D)
在回到装饰模式,其方法operation() 在执行前和执行后Q也可以对它大做文章。如此看来, Spring AOP ?DecoratorQ从理解层面上来看,实有点相象Q注意:只是理解层面Q?而他们的实现完全两马事!
其实主要是大家怎么看待q个问题Q按照本人的理解QSpring AOP 也可以说是一U广义的装饰Q但它又不是装饰模式。它同样也是Ҏ个方法加上了限制Q比如insert() 的时候,你要对它做执行前开启事务和执行后提交或回滚q样的“装饰”?又比如你也可以对某个人操作资源后做logq样的装饰工作。等{,Q?br />他们的相同之处就q么炏V?br />AOP 也不是什么新的东西,当然如果你的AOP是容?Jboss 4.0)实现的话Q?那么按照上面说的Q你的一些方法就会被容器所“装饰”?
如此看来Q更多的时候可以理解ؓ Spring AOP 和一些AOP 容器是在pȝU的Q容器的“装饰”?而装饰模式则是业务的装饰?q点其实从客L也很Ҏ理解?br />如果是AOP Q程序员可以攑ֿ的写你的代码Q即使有点笨也不怕,有AOP护着呢)?因ؓpȝ在pȝq行时候对q段代码q行“装饰”。也是_q些装饰不会出现在客L的代码中Q,Q而,Decorator模式呢?呵呵Q这个时候程序员要有点头脑了Q他们要自己l装一些装饰类Q按照某一U机制对Mq行装饰。也是_q些修饰c要出现在客L的代码中。看代码q道了 :--)


InputStreamReader input = new InputStreamReader(System.in);
BufferedReader br = new BufferedReader(input)Q?br />....
//M是System.in

?Q?够经典的例子Q?/font>



]]>
SOP入门---W一個Spring AOPE式 http://www.tkk7.com/wuxufeng8080/articles/53999.html风h?/dc:creator>风h?/author>Tue, 20 Jun 2006 07:42:00 GMThttp://www.tkk7.com/wuxufeng8080/articles/53999.htmlhttp://www.tkk7.com/wuxufeng8080/comments/53999.htmlhttp://www.tkk7.com/wuxufeng8080/articles/53999.html#Feedback0http://www.tkk7.com/wuxufeng8080/comments/commentRss/53999.htmlhttp://www.tkk7.com/wuxufeng8080/services/trackbacks/53999.html  來用Spring的AOP框架來重新撰寫之前「從代理制初探AOP」主中的程式,首先QSpring AOP預設使用動態代理來實作AOPQ動態代理必須宣告被代理物g的介面:

 代碼:

IHello.java
								package onlyfun.caterpillar; 

publicinterface IHello { 
    public void hello(String name); 
    public void morning(String name); 
}

  實作IHello介面的HelloSpeaker則如下:

 代碼:

HelloSpeaker.java
								package onlyfun.caterpillar; 

public class HelloSpeaker implements IHello { 
    public void hello(String name) { 
        System.out.println("Hello, " + name); 
    } 

    public void morning(String name) { 
        System.out.println("Morning, " + name); 
    } 
}

  我們希望在Ҏ埯前後進行a錄的動作,在AOP中這需要Around型的AdviceQ通常的,實作Around型的策略是使用Interceptor?

  Interceptor的一個例子是Servlet中的Filter制Q在Filter制下,當請求來臨時Q會被Filter先攔截並進行處理Q之後傳i下一個FilterQ最後才是真正處理請求的Servlet。實作AOP時所使用的Interceptor{略與Filter似Q所不同的是Filter被綁定於Servlet APIQ且只適用於請求階段?

  您可以將一連串的Interceptorx是堆疊結構,在Spring中,在真正執行某個方法前Q會先插入InterceptorQ每個Interceptor會執行自q處理Q然後再埯proceedQ這將埯程轉下一個InterceptorQ如果沒有下一個Interceptor了,執行真正呼叫的ҎQ方法執行過後,再一層一層返回Interceptor堆疊Q最後離開堆疊,如下圖,程先是紅色Q方法執行後的流E是藍色Q?

 代碼:

<-- --> interceptor1 <-- --> interceptor2 <-- --> ..... <-- --> Invoked method

  Spring在實作Interceptor時,是實作org.aopalliance.intercept.MethodInterceptorQAOP AllianceQ?span class="nobr">http://www.sourceforge.net/projects/aopallianceQ的目標是制定AOP功能的標準介面,目前只提供一部䆾的子集合Q子集包括了InterceptorQSpring實作MethodInterceptorQ以求將來Interceptor的可UL性?

  我們實作LogInterceptor如下Q?

 代碼:

LogInterceptor.java
								package onlyfun.caterpillar; 

import org.aopalliance.intercept.MethodInterceptor; 
import org.aopalliance.intercept.MethodInvocation; 
import java.util.logging.*; 

public class LogInterceptor implements MethodInterceptor { 
    private Logger logger = Logger.getLogger(this.getClass().getName()); 
    
   publicObject invoke(MethodInvocation methodInvocation) throws Throwable { 
        logger.log(Level.INFO, "method starts..." + methodInvocation.getMethod()); 
        try { 
          Object result = methodInvocation.proceed(); 
          return result; 
        } 
        finally { 
            logger.log(Level.INFO, "method ends..." + methodInvocation.getMethod() + "\n"); 
        }        
   } 
}

  invoke()中的MethodInvocation參數包括了下一個Interceptor的資a、被埯的方法、以及方法所需的參數,其返回值是被呼叫方法的q回倹{?

  我們還需要一個代理物Ӟ這可以用org.springframework.aop.framework.ProxyFactoryBeanQ它需要知道代理的介面與物Ӟ以及所要介入的InterceptorQ如下:

 代碼:

<?xml version="1.0" encoding="UTF-8"?> 
<!DOCTYPE beans PUBLIC "-//SPRING/DTD BEAN/EN""http://www.springframework.org/dtd/spring-beans.dtd"> 
<beans> 
    <bean id="logInterceptor" class="onlyfun.caterpillar.LogInterceptor"/> 

    <bean id="helloSpeaker" class="onlyfun.caterpillar.HelloSpeaker"/> 
    
    <bean id="helloProxy" class="org.springframework.aop.framework.ProxyFactoryBean"> 
        <property name="proxyInterfaces"> 
            <value>onlyfun.caterpillar.IHello</value> 
        </property> 
        <property name="target"> 
            <ref bean="helloSpeaker"/> 
        </property> 
        <property name="interceptorNames"> 
            <list> 
                <value>logInterceptor</value> 
            </list> 
        </property> 
    </bean> 
</beans>

  Interceptor埯的順序是interceptorNames中設定的順序Q最後是target目標物gQ用下面的E式來測試一下:

 代碼:

SpringTest.java
								package onlyfun.caterpillar; 

import org.springframework.context.*; 
import org.springframework.context.support.*; 

public class SpringTest { 
   publicstatic void main(String[] args) { 
        ApplicationContext context = new FileSystemXmlApplicationContext("bean.xml"); 
        IHello helloProxy = (IHello) context.getBean("helloProxy"); 
        helloProxy.hello("Justin"); 
        helloProxy.morning("momor"); 
    } 
}

  埯i果如下Q?

 代碼:

2004/11/26 上午 11:59:09 onlyfun.caterpillar.LogInterceptor invoke 
資訊: method starts...publicabstract void onlyfun.caterpillar.IHello.hello(java.lang.String) 
Hello, Justin 
2004/11/26 上午 11:59:09 onlyfun.caterpillar.LogInterceptor invoke 
資訊: method ends...publicabstract void onlyfun.caterpillar.IHello.hello(java.lang.String) 

2004/11/26 上午 11:59:09 onlyfun.caterpillar.LogInterceptor invoke 
資訊: method starts...publicabstract void onlyfun.caterpillar.IHello.morning(java.lang.String) 
Morning, momor 
2004/11/26 上午 11:59:09 onlyfun.caterpillar.LogInterceptor invoke 
資訊: method ends...publicabstract void onlyfun.caterpillar.IHello.morning(java.lang.String)

  完成了第一個Spring AOPE式了,不過這當中還有許多細可以說明Q下一個主再J續?/p>

]]>
վ֩ģ壺 ޹һƷ| ŷһ| Ƶ| 츾Ļʮг| ˾޾ƷӰԺ| һ֮| ɫaAV| ӰӾ߹ۿȫ | þþ뾫Ʒպ| avۺavһ | 1000žžʮδֹۿ | ŷŮƵ| 2016| 3344ѲŹۿƵ| ˳վ| պӰ߹ۿַ| ѸԴվ߹ۿ| ޹Ʒ˿߹ۿ| þѸƵ| ˴ֳսŮ2021ƷƵ| avavƷר| 츾avvrӰ| ߹ۿ| ޾Ʒ99߹ۿ| ŷۺһ| 91Դվ| ޾Ʒ˳| 弶18ѿ| mm1313޾Ʒ| gvh߹ۿ| պĻ| ŷպĻһ | ŮվɫƵѹ | þ91ѹۿ| þ99޸ۿҳ| ޾ƷɫƵ߹ۿԴ| www޾Ʒþþ| ŮֻѵƵ| ձ˳Ļ| AVƬ߹ۿ| ˸徫Ʒѹۿ|