<<Spring in Action>> 学习总结(1)

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 处理国际化,配置成

<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 类:

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(可能是多个重载方法)启用事物

<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 属性中可以指定哪个类的哪个方法,可以使用通配符
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值