`
z274084093
  • 浏览: 17348 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
最近访客 更多访客>>
社区版块
存档分类
最新评论

<Spring in Action>

阅读更多

1. <ref>标签中的 bean, local, parent 三个属性的区别

2. <list><value...</list>和<set><value...< /list>可以换着用都可以为 List, Set 以及数组属性赋值

3. <map>属性用 spring  进行装匹时 key 值只能是字符串类型,不过一般能满足要求

4. 装配 map 属性要用 <entry key="key1"><value>foo</value></entry>, 而装匹 properties 属性可以写成 <prop key="key1">foo</prop>, 这是因为 properties 的值总是字符串,而 map 中很随意

5. 用 <property name="foo"><null/></property> 形式设置属性为 null, 区别为字符串 "null"

6. 通过构造函数注入依赖时,对多参数需要借助于 index 或 type 属性来指定对应哪个参数,index 属性能应付所有情况

7. 可为 bean 设置 autowire为四个值, byname, byType, constructor, autodetect, 四种方式自动装匹;也可以在 <beans> 中设置 defaul-tautowire 属性。手动和自动可以混合使用,手动优先。你应该清楚自己在做什么,所以不建议用自动装配

8. BeanPostProcessor的方法 postProcessBeforeInitialization 在 bean 初始化之前调用,postProcessAfterInitialization 是在 bean 初始化之后调用,需要注册到 BeanFactory 上,如 factory.addBeanPostProcessor(new BeanPostProcessor(){...})。内置的 ApplicationContextAwareProcessor 注册在了 AbstractApplicationContext 上了

9. BeanFactoryPostProcessor 是在 Bean 工厂载入所有 Bean 定义后,实例化 Bean 之前作处理。如果是 AbstractApplicationContext ,那么只需要配置 <bean id="myBeanFactoryPostProcessor" class="com.unmi.MyBeanFactoryPostProcessor"/>, 则会自动注册这个,原有的 BeanFactoryPostProcessor 不可用了,不需要显示式的调用 addBeanFactoryPostProcessor 方法

10. 可用 PropertyPlaceholderConfigurer 载入属性文件,然后在其他引用 value 的地方用 ${database.url} 的方式引用

11. 用 CustomEditorConfigurer 注册自己的 PropertyEditorSupport 关联特定的 bean 属性的处理,可了解 Spring 有哪些内置的 PropertyEditorSupport

12. Spring 用 ResourceBundleMessageSource 处理国际化,配置成

Java 代码
  1. <bean id= "messageSource"  
  2. class = "org.springframework.context.support.ResourceBundleMessageSource" >  
  3.     <property name="basename" >  
  4.        <value>trainingtext</value>  
  5.     </property>   
  6.   </bean>  
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">     <property name="basename">        <value>trainingtext</value>     </property>    </bean>


会读取 trainingtext.prperties, trainingtext_en_US.properties 等。
用 Sring text = context.getMessage("button.submit", new Object[0],locale); 或 <sping:message code="button.submit"/> 读取


13. 监听事件,配置实现了ApplicationListener的Bean,容器会自动注册它,发布ApplicationEvent时由它处理,事件的处 理是同步的

14. Bean 实现了 BeanNameAware, BeanFactoryAware 或 ApplicationContextAware 可以感知它自己或所处环境的信息,但这样做却让 Bean 与 Spring 框架耦合起来了

15. AOP: spring 有两种代理创建方式,对接口方法用JDK的java.lang.reflect.Proxy类创建代理,对于未实现接口的借助于cglig库生成目标对象 的子类,标记为 final 的方法不能被通知,因为子类中不能覆写该方法。

16. Spring 只支持方法连接点,应该也是秉着够用就行的道理,直接用 AspectJ 将能做十分细致的活

17. MyEclipse 提供了一种快捷方式来写Bean的配置,从左树上把类拖到打开的 Spring 的配置文件中依提示行事即可,实际使用中看是否真正实用

18. 在 MethodBeforeAdvice中可以抛异常或System.exit()阻止目标方法的执行,如果此时抛出的异常是 RuntimeException 或者目标方法申明的异常,将会被 Spring 框架捕获


19. MethodInterceptor 能控制目标方法是否真的被调用,用 methodInvocation.proceed() 调用目标方法

20. MethodInterceptor 可以返回一个与目标方法不同的对象,但也必须是兼容的,否则出现 ClassCastException 异常

21. 实现接口 ThrowsAdvice 的类,必须至少有一个如下形式方法:
1)void afterThrowing(Throwable throwable)
2)void afterThrowing(Method method, Object[] args, Object target, Throwable throwable)
在 ThrowsAdvice 并没有象 MethodBeforeAdvice, MethodAfterAdvice 和 MethodInterceptor 定义了要实现的方法,只是一个不成文的约定,不知作者是如何考虑的,怕定义了两个方法后实现类要实现两个方法(可能只需用到一个方法)而麻烦吗?那至少可 以弄一个 ThrowsAdviceAdapter 的东西,Spring 中还确实有这玩艺,但不是那么回事。
这种 ThrowsAdvice 对实现类不成文的规定,让在 IDE 中写代码不方便,也容易产生错误

22. 当你的 ThrowsAdvice 同时实现了上面两个方法时,只有参数多的那个方法有效,只实现第一个方法也是可以的,所以在 ThrowsAdvice 的源代码中只提到要实现第二个方法,所以我就更想不能了,为什么在接口 ThrowsAdvice 中不定义这个方法呢?


23. 记录几个书中错误:54页的java.awt应该是java.util。94页的maidService配置中的 frequentCustomerAdvisor应该是  frequentCustomerPointcutAdvisor。108页,后面两个 proxyInterfaces 应该是 interceptorNames

24. 用 NameMatchMethodPointAdvisor 能简单的用通配符控制切入点,但要细致的控制切入点就要用 RegexpMethodPointcutAdvisor 结合正则表达式了, 它可含有类名信息,而 nameMatchMethodPointAdvisor只需考虑方法名的匹配

25. 动态切入点的配置方法与静态切入点略有不同,需要申明一个ControlFlowPointcut的Bean(Pointcut)作为 DefaultPointcutAdvisor的pointcut属性,然后这个advisor配置到ProxyFactoryBean的 interceptorNames,所以想,既然是叫做DefaultPointcutAdvisor,那么是不是别的Pointcut也可以通过这种方 式来配置呢?动态切入点很损耗性能,非必要是不用,对JDK1.4会慢5位,对JDK1.3会慢10,对于JDK1.5恐怕也好不到哪儿去

26. 觉得 Spring 的引用 IntroductionInterceptor 用起来特麻烦,远没有直接用 AspectJ 来的方便与简练

27. 配置 ProxyFactoryBean 时不指定 proxyInterfaces 属性,直接指定 target 为Class,则会用CGLIB生成目标类的子类。即使指定的 proxyInterfaces 属性,设置 ProxyTargetClass 属性为 true,也会用 CGLIB 生成目标类的子类,而不是用JDK的动态代理

28. 配置 ProxyFactoryBean 时可以把 target 目标对象配置为interceptorNames的最后一个属性

29. 强大的自动代理:BeanNameAutoProxyCreator 和 DefaultAdvisorAutoProxyCreator。DefaultAdvisorAutoProxyCreator实现了 BeanPostProcessor 接口,它只能与 Advisor 配合使用,自动的处理所有的 Advisor

30. 看到29条中的自动代理,让我回想起可以为一批 Bean 批量的增加 toString() 方法,只是那些 bean 必须通过 getBean()得来才能看到效果

31. Spring 把数据访问流程中的固定部分和可变部分分开,分别映射成两截然不同的类,模板(Template)和回调(Callback),模板管事物控制、资源管理 以及异常处理;回调实现特定于应用的部分--创建 statement、绑定参数、以及整理结果集。模板方法模式的优秀应用

32. JdbcTemplate template = new JdbcTemplate(myDataSource); 构造。 所有 Spring Dao 模板类是线程安全的,可以为每一个 DAO 配置一个 JdbcTemplate 属性,也可以让 DAO 类继承 JdbcDaoSupport,然后在 DAO 类中用 getJdbcTemplate() 获取到 JdbcTemplate 进行数据库操作。书中的做法是给每个 Dao 加一个 JdbcTemplate 属性,记录的日志略有不同,实际中注意

33. JdbcTemplate 的 execute() 方法不可带 sql 参数,而 update() 方法可以,还能指定每一字段的类型,保证了类型安全,130页说 JdbcTemplate 提供了 execute(String sql, Object[] params) 是错误的


34. JdbcTemplate 类创建了 PreparedStatementCreator 和 PreparedStatementSetter,  批量更新时需要创建自己的 BatchPreparedStatementCreator 类:

Java 代码
  1. BatchPreparedStatementSetter setter =  new  BatchPreparedStatementSetter(){  
  2.     public   int  getBatchSize(){  return  persons.size();}  
  3.     public   void  setValues(PreparedStatement ps,  int  index)  throws  SQLException{  
  4.         Person person = (Person) persons.get(index);  
  5.         ps.setInt(0 ,person.getId().intValue());  
  6.           
  7.     }  
  8. };  
BatchPreparedStatementSetter setter = new BatchPreparedStatementSetter(){         public int getBatchSize(){ return persons.size();}         public void setValues(PreparedStatement ps, int index) throws SQLException{             Person person = (Person) persons.get(index);             ps.setInt(0,person.getId().intValue());                      }     };


getJdbcTemplate().batchUpdate(sql,setter);
把传入的List<Person>批量的进行数据库相应操作

35. 用JdbcTemplate读数据,可以用 JdbcTemplate.query(sql,params, rowCallbackHandler), 实现 RowCallbackHandler的 processRow(ResultSet rs) 组装查询到的一个对象。实现自己的 RowMapper把 ResultSet 中一条记录映射成一个对象,用JdbcTemplate.query(sql, params, new MyRowMapper())能够返回查询整理后的对象列表,书中 133 页的带 RowMapperResultReader的query方法已经不存在了。由此可见,即使是只返回一条记录的查询也可用带 RowMapper的query方法,只需返回第一条记录就行

36. JdbcTemplate的 queryForXXX可更快捷返回简单的查询值,如一个 count, 只返回一条记录的一个字段的值

37. JdbcTemplate 调用存储过程: jdbcTemplate.execute("{ARCHIVE_STUDENTS}", new CallableStatementCallback(){.....}); 看清了,就是要实现自己的 CallableStatementCallback的一个方法
public Object doInCallableStatement(CallableStatement cs){
cs.execute();
return null;
}

38. 不接使用 JdbcTemplate, 扩展 SqlUpdate 和 MappingSqlQuery的用法。扩展 DataFieldMaxValueIncrementer 取得自增键值,有三个方法 nextIntValue()、nextLongValue()、nextStringValue(),根据实际数据库可以用不同的实现


39. Acegi 安全系统由4个主要组件:
1)安全拦截器:拦载下用户,要求提求用户名与口令
2)认证管理器:进行用户名与口令的验证
3)访问决策管理器:进访问资源进行授权
4)更多的安全限制检验


40. 认证管理器接口是 AuthenticationManager,它的实现在是 ProviderManager, providerManager 具体是委派给 AuthenticationProvider 去处理,AuthenticationProvider接口与 AuthenticationManager 接口有完全相同的方法

41. 337页配置中的 <property name="authenticationDao"> 应该是 <property name="userDetailsService">,Acegi 的包名也由原来的 net.sf.acegisecurity 变成了 org.acegisecurity,跟个 hibernate3 似的

42. Spring提供了两种与 Struts 集成的方式
1)让你的Action继承 ActionSupport
2) 让 Spring 管理你的 action

43. 为了让 Struts 能访问 Spring 管理的 Bean,必须在 struts-config.xml 中注册 ContextLoaderPluIn,用的是 WebapplicationContext

44.  ActionSupport 重载了 setServlet()方法,获取bean的方式为getWebApplicationContext().getBean()

45. 继承 ActionSupport 让 Struts与Spring 紧密耦合,而且 Action 还负责查找 Bean,这也违背了IoC原则

46. 使用委托 Action:Struts-config.xml 中每个path都指定type为org.springframework.web.struts.DelegatingActionProxy,实际的 Action实例由Spring来管理,它们之间用path<->name来映射,这种方式并不好看

47. 使用请求委托,只在Struts-config.xml中配置 DelegatingRequestProcess或DelegatingTilesRequestProcessor作为控制器,其余配置不变, 如<action path="/listCourses" type="com.unmi.MyCoursesAction"/>其实type属性是被所配置的controller忽略掉了,所以可省去 type属性 ction也是由Spring来配置装配,也是通过 path--name来对应

48. 感觉Spring与Struts的搭配总有些牵强,没有一种更完美的方式

49. HibernateDaoSupport有getSession()和closeSessionIfNecessary(),可取得Session作更自 由的操作


50. DaoSupport有以下实现类:CciDaoSupport, HibernateDaoSupport, JdbcDaoSupport, JdoDaoSupport, PersistenceBrokerDaoSupport, SqlMapClientDaoSupport, SqlMapDaoSupport, TopLinkDaoSupport,据此了解支持哪些类型DB操作

51. 要用声明式事物,需要用到 TransactionProxyFactoryBean 来包括你的 Service 类。

52. 能够简单配置被代理的Service的 transactionAttributes 属性声明事物,如下对方法名称为addStudent(可能是多个重载方法)启用事物

Java 代码
  1.  <property name= "transactionAttributes" >  
  2.     <props>  
  3.         <prop key="addStudent" >  
  4.             PROPAGATION_REQUIRES_NEW,ISOLATION_DEFAULT  
  5.         </prop>  
  6.     </props>  
  7. </property>  
<property name="transactionAttributes">             <props>                 <prop key="addStudent">                     PROPAGATION_REQUIRES_NEW,ISOLATION_DEFAULT                 </prop>             </props>         </property>


如果没为某个 service 方法配置事物,它是能自动提交的。


52. 配置属性 transactionAttributeSource为 MatchAlwaysTransactionAttributeSource 实例,将使 TransactionProxyFactoryBean 的目标类代理的方法都被执行在一个事务环境中了,默认为 PROGAGATION_REQUIRED,ISOLATION_DEFAULT

53. 可配置 DefaultTransactionAttribute 给 MatchAlwaysTransactionAtributeSoure 的 transactionAttribute 属性,改变 MatchAlwaysTransactionAtributeSoure 的默认事物属性

54. 使用 NameMatchTransactionAttributeSource 可能实现像在 CMT 中那样的事物属性配置。可设定事物回滚规则:默认情况下,发生 Runtime 异常回滚;发生checked exception 不回滚(这也是EJB的行为),可定制,用正(+)或负(+)号写在异常类名前,正异常表示事务仍可提交,负异常表示触发回滚

55. NameMatchTransactionAttributeSource 应该能想像到,支持方法名的通配符形式,如 key="get*",应用到所有以get开始的方法

56. NameMatchTransactionAttributeSource 的简洁配置,直接配置给 TransactionProxyFactoryBean 的 transactionProperties 属性,形式如它的 properties 属性配置,内部实现是会帮你构造 NameMatchTransactionAttributeSource 实例。在 Spring 1.2.8 中的 TransactionProxyFactoryBean 都没有 transactionProperties

57. 可以用元数据来书写事物属性,JDK1.5 版以下需借助于 Jakarta Commons Attributes,而且还需要结合 ANT 预编译,麻烦,如果是JDK1.5以上就方便多了。要使用到 AttributesTransactionAttributeSource

58. 使用 Bean 继承可以在父 bean (TransactionProxyFactoryBean)中定义公共的东西,如 transactionManager,transactionAttributeSource 等,子 bean 中只需要定义自己的 target 属性,这样做可以省却很多 XML 配置。注意父 Bean 当抽象类使用,不需要用到它的实例,所以设置 lazy-init="true" 告诉容器不要初始化它


59. 更为精彩的是自动代理的方式来总体配置各分散类中方法的事物属性,结合使用 DefaultAdvisorAutoProxyCreator, TransactionAttributeSourceAdvisor 和 TransactionInterceptor (我还需要详细理清楚)

60. 当使用自动代理时,MethodMapTransationAttributeSource 就能很多的派上用场了,它的 methodMap 属性中可以指定哪个类的哪个方法,可以使用通配符

 

61. 对于 JndiObjectFactoryBean 查找 jndi  资源未提及,如何设置 jndiEnvironment 属性,如果是在J2EE容器中运行,没什么问题,只是以单独应用程序运行就会错,如下在容器外运行需要加上 jndiEnvironment 配置,指定实现类,及URL等

Java 代码
  1. <property name= "jndiEnvironment" >  
  2.      <props>  
  3.          <prop key="java.naming.factory.initial" >  
  4.              org.apache.naming.java.javaURLContextFactory  
  5.          </prop>  
  6.          <prop key="java.naming.factory.url.pkgs" >  
  7.              org.apache.naming  
  8.          </prop>  
  9.      </props>  
  10.  </property>  
<property name="jndiEnvironment">       <props>           <prop key="java.naming.factory.initial">               org.apache.naming.java.javaURLContextFactory           </prop>           <prop key="java.naming.factory.url.pkgs">               org.apache.naming           </prop>       </props>   </property>



62.发送电子邮件配置 SimpleMailMessage 时也未说明,如果 SMTP 发送前需要验证该如何配置。需加上 mail.smtp.auth属性为 true,和验证时用户名和密码,Spring 验证时是通过 getTransport("smtp").connect(host,user,passwd) 来验证的。

Java 代码
  1. <bean id= "mailSender"   class = "org.springframework.mail.javamail.JavaMailSenderImpl" >  
  2.         <property name="javaMailProperties" >  
  3.             <props>  
  4.                 <prop key="mail.smtp.auth" > true </prop>  
  5.             </props>  
  6.         </property>  
  7.         <property name="host" >  
  8.             <value>mail.2911 .net</value>  
  9.         </property>  
  10.         <property name="username" >  
  11.             <value>unmi</value>  
  12.         </property>  
  13.         <property name="password" >  
  14.             <value>unmi1234</value>  
  15.         </property>  
  16.     </bean>  
<bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">         <property name="javaMailProperties">             <props>                 <prop key="mail.smtp.auth">true</prop>             </props>         </property>         <property name="host">             <value>mail.2911.net</value>         </property>         <property name="username">             <value>unmi</value>         </property>         <property name="password">             <value>unmi1234</value>         </property>     </bean>


这样取到mailSender后,就能调用它的send(SimpleMailMessage msg)发送邮件,自动进行密码验证。Spring也还是不够完美,可以配置 JavaMailSenderImpl 的 session 属性,但却无法应用上 session.getProperties() 中的许多项配置。Spring中能配置 SimpleMailMessage,然后再配合 Velocity 的邮件内容模板,确实很方便


63. 搭配Spring的ScheduledTimerTask和jdk的TimerTask,再配置TimerFactoryBean就会自动启动定时器了, 这种方式可配置的参数太少了,只能设置从现在开始隔多久(delay)以什么频度(period)执行某个任务

64. 更高级的定时器用 Quartz 来调度,这个工具以前单独使用过,可像Unix的cron那般灵活配置。在MyEclipse中使用Quartz时需要引入 Spring 1.2 Misc Libraries 所包含的包(含quartz-1.5.2.jar)

65. 94,96,97,104这几页中配置<value ref=""/>要写成<ref bean=""/>才对

66. 从前往后的被包容关系是:JobClass->JobDetailBean->Trigger->TimerFactoryBean, 有两种Trigger,分别是 SimpleTriggerBean 和 CronTriggerBean。SimpleTriggerBeanScheduledTimerTask基本等价,Quartz的威力全部体现在 CronTriggerBean 上的,可灵活的配置它的cronExpression属性控制排程,最后需配置 SchedulerFactoryBean (它和TimerFactoryBean是基本等价) 来启动定时器

67. MethodInvokingTimerTaskFactoryBean+ScheduledTimerTask+TimerFactoryBean 可定时调用某个类(或对象)的某个方法,这个类只需要是一个普通Java类,被调度的方法不能有参数

68. MethodInvokingJobDetailFactoryBean+SimpleTriggerBean(或 CronTriggerBean)+SchedulerFactoryBean 定时调用某个类(或对象)的某个方法,这个类只需要是一个普通Java类,被调度的方法不能有参数

69. 书中并未描述 0/10 每10个单位触发执行的配置形式,需注意 */? 的使用,定义好 CronExpression 后需好好测试真正形为

70. Spring 调用 JMS 发送消息的用法先搁一下,在SOA/MQ 的大环境下一定派得上用场的

Spring mvc

71. Spring 的 MVC 和 Struts 的 MVC 基本一致
Spring 的控制流程是:请求->DispatcherServlet->从 HandlerMapping 中查询到处理该请求的 Controller-> Controller 的 handleRequest 方法调用业务方法,最后返回 ModelAndView (ModelAndView告诉了 DispatcherServlet 转向到哪个视图)
Struts 的控制流程是:请求->ActionServlet->从 ActionMapping 中查询到处理该请求的 Controller (Action类)->Action 的execute 方法调用业务方法,最后返回 ActionForward (ActionForward告诉了 ActionServlet 该转向到哪个视图)
72. Spring 的 DispatcherServlet 和 Struts 的 ActionServlet 的配置方式是一样的,都是作为一个自启动的 Servlet 配置到 web.xml 中。Spring 的 url-pattern 的配置惯例是 *.htm,而 Struts 通常是配置成 *.do 或 *.action,它暴露了 web 使用的技术。


73. Spring 中配置了

Java 代码
  1. <servlet-mapping>  
  2.        <servlet-name>unmi</servlet-name>  
  3.        <url-pattern>*.html</url-pattern>  
  4.    </servlet-mapping>  
<servlet-mapping>         <servlet-name>unmi</servlet-name>         <url-pattern>*.html</url-pattern>     </servlet-mapping>


后,在初始化相应的 DispatcherServlet 时会自动加载 unmi-servlet.xml 文件,它是一个普通的 Spring Bean 配置文件,也是由 WebApplicationContext 加载。其他的 Bean 配置文件需要像通常的做法由 ContextLoaderListener 或 ContextLoaderServlet 来加载。

73. Struts 1.2? 后开始可以在 struts-cnfig.xml 中给 Action 注入简单属性,而 Spring 配置 controll 时可以注入所有类型属性

74. 在 unmi-servlet.xml 中配置的下面这段代码,Spring 将对请求 URL 是 "/home.html" 结尾的分派给 HomeController 处理,DispatcherServlet 使用的默认处理器映射是 BeanNameUrlHandlerMapping

Java 代码
  1.  <bean name= "/home.html"   class = "com.unmi.HomeController" >  
  2.     <property name="greeting" ><value>Welcome to Spring Training</value></property>  
  3. </bean>  
<bean name="/home.html" class="com.unmi.HomeController">     <property name="greeting"><value>Welcome to Spring Training</value></property> </bean>



75. Spring 最简单的视图解析器是 InternalResourceViewResoler,如在 unmi-servlet.xml 有下配置

Java 代码
  1. <bean id= "viewResolver"   class = "org.springframework.web.servlet.view.InternalResourceViewResoler" >  
  2.    <property name="prefix" ><value>/WEB-INF/jsp/</value></proeprty>  
  3.    <property name="surfix" ><value>.jsp/</value></proeprty>  
  4. </bean>  
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResoler">    <property name="prefix"><value>/WEB-INF/jsp/</value></proeprty>    <property name="surfix"><value>.jsp/</value></proeprty> </bean>


那么,当 HomeController 中 返回 return new ModelAndView("home"); 时将会解析成由视图 /WEB-INF/jsp/home.jsp 来展示

76. 有三种类型的请求映射控制器,实现的是 HandlerMapping 接口
BeanNameUrlHandlerMapping -- 根据控制器的名字将控制器映射到 URL
SimpleUrlHandlerMapping -- 用上下文配置文件中定义的属性集合将控制器映射到 URL
CommonsPathMapHandlerMapping -- 使用控制器代码中的元数据将控制器映射到 URL
DispatcherServlet 缺省映射处理器是 BeanNameUrlHandlerMapping,它将表现层 URL 和控制器名字绑定起来了, Spring 不建议使用这个映射处理器,建议用 SimpleUrlHandlerMapping。可是我觉得用 BeanNameUrlHandlerMapping 挺方便的啊

77. 使用 SimpleUrlHandlerMapping 的配置,需要将系统中用到的 URL 一一逻列出来

Java 代码
  1. <bean id= "simpleUrlMapping"   class = "org.springframework.web.servlet.handler.SimpleUrlHandlerMapping" >  
  2.     <property name="mappings" >  
  3.         <props>  
  4.             <prop key="/listCourse.html" >listCoursesController</prop>  
  5.             <prop key="/register.htm" >registerStudentController</prop>  
  6.         </props>  
  7.     </peroperty>  
  8. </bean>  
<bean id="simpleUrlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">     <property name="mappings">         <props>             <prop key="/listCourse.html">listCoursesController</prop>             <prop key="/register.htm">registerStudentController</prop>         </props>     </peroperty> </bean>



78. 使用 CommonsPathMapHandlerMapping 需要为 Controller 类注解上 PathMap 属性为一个 URL

79. 可用同时配置多映射处理器,通过配置它们实现的 Ordered 接口的 order 属性,DispatcherServlet 按顺序采用哪个映射处理器(责任链模式)

80. Spring 提供了丰富的控制器层次,方便根据实际需求选择实现或继承那一种控制器

81. 继承 AbstractController 要覆盖的方法是 handleRequestInternal(request,response);
new ModelAndView("counrseList","courses",courses) 第一个参数是 view 的逻辑名,第二第三个参数是传递给 view 的名称/数值对

82. 当控制器需要根据参数执行工作时,应该继承 AbstractCommandController , 你的 Controller 中需要覆盖 handle 方法,并且需要在构造函数中指定命令类,如

Java 代码
  1. public  MyController(){  
  2.         setCommandClass(MyCommand.class );  
  3.     }  
public MyController(){         setCommandClass(MyCommand.class);     }


在使用 Command 对象与 Struts 中是一样的,在 handle 方法中用 MyCommand myCommand = (MyCommand)command,不同的就是 Struts 的 FormBean 是作为 execute 方法存在,而 Spring 的 command 是作为成员存在。
命令对象只是一个 POJO,功能相当于 Struts 的 Action,能匹配接受请求中的参数,它不需要在 Spring 的配置文件中配置。留下一个疑问:要是 AbstractCommandController 能在 Spring 的配置文件中注入可能要好些,相当于 Struts 的 Action 的 FormBean 也是在 struts-config.xml 配置给 Action 的
自己试了一下,可以通过配置给 commandClass 一个全限类名字符串注册 class 属性,Spring 提供了相应的属性编辑器

Java代码
  1. <property name= "commandClass" >  
  2.             <value>com.unmi.MyCommand</value>  
  3.         </property>  
<property name="commandClass">             <value>com.unmi.MyCommand</value>         </property>



83. AbstractFormController 有一个子类 SimpleFormController,它声明了两个属性 formView 和 successView,分别对应了在处理请求出现异常和正常时对应的 View 的逻辑名,这两个属性需要在配置文件中给配上,在你的 SimpleFormController 类中覆盖 void doSubmitAction(Object command) throws Exception 将会使用到它们,注意这个方法没有返回值的。你也可以覆盖 ModelAndView onSubmit(Ojbect command),向 View 中传递数据,return new ModelAndView(getSuccessView(),"student",student); 像 AbstractCommandController 一样,需要在构造函数中指定 Command 类,可是看那两个submit 方法,command 再一次通过参数传入到方法,真的有些多此一举

84. 验证表单输入, 你的验证类必须实现 org.springframework.validation.Validator 接口,supports()方法帮助判断验证器是否适用于指定类,在 validate(Object command, Errors errors) 用 Errors 驳回任何非法数据,如

Java 代码
  1. ValidationUtils.rejectIfEmpty(errors,  "login" "required.login"   "Login is required" );  
  2.     if (! new  Perl5util().match(PHONE_REGEXP,phone){  
  3.         errors.reject("invalide.phone" , "Phone number is invalid" );  
  4.     }  
ValidationUtils.rejectIfEmpty(errors, "login", "required.login" "Login is required");     if(!new Perl5util().match(PHONE_REGEXP,phone){         errors.reject("invalide.phone","Phone number is invalid");     }


最后,你需要把验证类注入给你的 CommandController 的 validator 属性

Java 代码
  1. <property name= "validator" >  
  2.       <bean class = "com.unmi.MyValidator" />  
  3.   </property>  
<property name="validator">         <bean class="com.unmi.MyValidator"/>     </property>



validate 方法会在 AbstractCommandController .handleRequestInternal(request,response) 调用,SimpleFormController.onSubmit() 会在调用 doSubmitAction() 之后,把 errors 传递给 View。以后要搞清楚错误信息要如何显示出来

85. Spring 提供了 AbstractWizardFormController 来简化跨越多个页面处理表单的工作 (向导式页面表单),这是 Struts 所没有的功能。您只需要覆盖 processFinish(request,response,command,errors)方法,在最后一个页面提交后将会被调用处理收集的数据, 向导中的页面流程配置到 AbstractWizardFormController 的 pages 属性,如下

Java 代码
  1. <bean id= "feedbackController"   class = "com.unmi.FeedbackWizardController" >  
  2.     <property name="pages" >  
  3.         <list>  
  4.             <value>general</value> <!-- 填 写一般性问题 -->  
  5.             <value>instructor</value>  <!-- 填 写导师绩效的问题 -->  
  6.             <value>course</value>  <!-- 填 写课程内容和教材问题 -->  
  7.             <value>facilities</value>  <!-- 填 写质量问题 -->  
  8.         </list>  
  9.     </property>  
  10. </bean> 
分享到:
评论

相关推荐

    Spring in Action 中文版 第五部分(Spring in Action CN.005)

    Spring in Action CN.001&lt;br&gt;Spring in Action CN.002&lt;br&gt;Spring in Action CN.003&lt;br&gt;Spring in Action CN.004&lt;br&gt;Spring in Action CN.005&lt;br&gt;Spring in Action CN.006&lt;br&gt;Spring in Action CN.007&lt;br&gt;Spring in ...

    Spring in Action 中文版 第二部分(Spring in Action CN.002)

    Spring in Action CN.001&lt;br&gt;Spring in Action CN.002&lt;br&gt;Spring in Action CN.003&lt;br&gt;Spring in Action CN.004&lt;br&gt;Spring in Action CN.005&lt;br&gt;Spring in Action CN.006&lt;br&gt;Spring in Action CN.007&lt;br&gt;Spring in ...

    Spring in Action 中文版 第四部分(Spring in Action CN.004)

    Spring in Action CN.001&lt;br&gt;Spring in Action CN.002&lt;br&gt;Spring in Action CN.003&lt;br&gt;Spring in Action CN.004&lt;br&gt;Spring in Action CN.005&lt;br&gt;Spring in Action CN.006&lt;br&gt;Spring in Action CN.007&lt;br&gt;Spring in ...

    Spring in Action 中文版 第三部分(Spring in Action CN.003)

    Spring in Action CN.001&lt;br&gt;Spring in Action CN.002&lt;br&gt;Spring in Action CN.003&lt;br&gt;Spring in Action CN.004&lt;br&gt;Spring in Action CN.005&lt;br&gt;Spring in Action CN.006&lt;br&gt;Spring in Action CN.007&lt;br&gt;Spring in ...

    Spring in Action 中文版 第七部分(Spring in Action CN.007)

    Spring in Action CN.001&lt;br&gt;Spring in Action CN.002&lt;br&gt;Spring in Action CN.003&lt;br&gt;Spring in Action CN.004&lt;br&gt;Spring in Action CN.005&lt;br&gt;Spring in Action CN.006&lt;br&gt;Spring in Action CN.007&lt;br&gt;Spring in ...

    Spring in Action 中文版 第九部分(Spring in Action CN.BAT)

    Spring in Action CN.001&lt;br&gt;Spring in Action CN.002&lt;br&gt;Spring in Action CN.003&lt;br&gt;Spring in Action CN.004&lt;br&gt;Spring in Action CN.005&lt;br&gt;Spring in Action CN.006&lt;br&gt;Spring in Action CN.007&lt;br&gt;Spring in ...

    Spring in Action 中文版 第八部分(Spring in Action CN.008)

    Spring in Action CN.001&lt;br&gt;Spring in Action CN.002&lt;br&gt;Spring in Action CN.003&lt;br&gt;Spring in Action CN.004&lt;br&gt;Spring in Action CN.005&lt;br&gt;Spring in Action CN.006&lt;br&gt;Spring in Action CN.007&lt;br&gt;Spring in ...

    Spring in Action 中文版 第一部分(Spring in Action CN.001)

    Spring in Action CN.001&lt;br&gt;Spring in Action CN.002&lt;br&gt;Spring in Action CN.003&lt;br&gt;Spring in Action CN.004&lt;br&gt;Spring in Action CN.005&lt;br&gt;Spring in Action CN.006&lt;br&gt;Spring in Action CN.007&lt;br&gt;Spring in ...

    Spring In Action中文 第五部分

    ”&lt;br&gt;——Jack Herrington,Code Generation in Action的作者 &lt;br&gt;----总共8部分rar下载完后解压 -----&lt;br&gt;Spring in Action. 中文版.part1.rar&lt;br&gt;Spring in Action. 中文版.part2.rar&lt;br&gt;Spring in Action. 中文...

    Spring In Action中文 第六部分

    ”&lt;br&gt;——Jack Herrington,Code Generation in Action的作者 &lt;br&gt;----总共8部分rar下载完后解压 -----&lt;br&gt;Spring in Action. 中文版.part1.rar&lt;br&gt;Spring in Action. 中文版.part2.rar&lt;br&gt;Spring in Action. 中文...

    Spring In Action中文 第七部分

    ”&lt;br&gt;——Jack Herrington,Code Generation in Action的作者 &lt;br&gt;----总共8部分rar下载完后解压 -----&lt;br&gt;Spring in Action. 中文版.part1.rar&lt;br&gt;Spring in Action. 中文版.part2.rar&lt;br&gt;Spring in Action. 中文...

    spring in action chinese copy part2

    a classic reference &lt;spring in action&gt; chinese version

    spring in action chinese copy part1

    a classic reference &lt;spring in action&gt; chinese version

    Spring In Action中文 第八部分

    ”&lt;br&gt;——Jack Herrington,Code Generation in Action的作者 &lt;br&gt;----总共8部分rar下载完后解压 -----&lt;br&gt;Spring in Action. 中文版.part1.rar&lt;br&gt;Spring in Action. 中文版.part2.rar&lt;br&gt;Spring in Action. 中文...

    Spring In Action中文 第一部分

    ——Jack Herrington,Code Generation in Action的作者 &lt;br&gt; ----总共8部分rar下载完后解压 -----&lt;br&gt; Spring in Action. 中文版.part1.rar&lt;br&gt; Spring in Action. 中文版.part2.rar&lt;br&gt; Spring in Action. 中文版....

    Spring In Action中文 第二部分

    ——Jack Herrington,Code Generation in Action的作者 &lt;br&gt; ----总共8部分rar下载完后解压 -----&lt;br&gt; Spring in Action. 中文版.part1.rar&lt;br&gt; Spring in Action. 中文版.part2.rar&lt;br&gt; Spring in Action. 中文版....

    Spring In Action中文 第四部分

    ——Jack Herrington,Code Generation in Action的作者 &lt;br&gt; ----总共8部分rar下载完后解压 -----&lt;br&gt; Spring in Action. 中文版.part1.rar&lt;br&gt; Spring in Action. 中文版.part2.rar&lt;br&gt; Spring in Action. 中文版....

    原创 Struts Spring Hibernate (SSH) 整合实例

    &lt;servlet-name&gt;action&lt;/servlet-name&gt; &lt;servlet-class&gt;org.apache.struts.action.ActionServlet&lt;/servlet-class&gt; &lt;init-param&gt; &lt;param-name&gt;config&lt;/param-name&gt; &lt;param-value&gt;/WEB-INF/struts/struts.xml&lt;/...

    Manning Spring in Action 2nd Edition

    PART 1 CORE SPRING ...............................................................1&lt;br&gt;1 ■ Springing into action 3&lt;br&gt;2 ■ Basic bean wiring 31&lt;br&gt;3 ■ Advanced bean wiring 72&lt;br&gt;4 ■ Advising beans ...

Global site tag (gtag.js) - Google Analytics