欢迎使用我的 在线工具

小D

读历史、看小说、写程序都是我所爱。技术不好,头脑不灵光,靠的是兴趣。
随笔 - 35, 文章 - 25, 评论 - 13, 引用 - 0
数据加载中……

Spring jpetstore 阅读笔记

1.org.springframework.beans.support.PagedListHolder
PagedListHolder 是一个简单状态的,可以处理对象列表的持有者,它将这些对象分成页面。页号从0开

始。
这个主要在WEB UI中使用。具有代表的,一个实例将被以列示一列bean,将它们放置到session中,然后

将它们导出为一个model(模型)。所有的属性将程序化set/get,但是最常用的方式是数据绑定,例如组

装请求参数中的bean。View层中主要用到getter方法。
使用一个属性“sort”,将通过一个SortDifinition实现将基本的list排序。默认,一个

MutableSortDefinition实例将被使用,使用相同的属性将递增给定的值。
 BeanWrapper要求,绑定数据名必须被称作“pageSize”和 “sort.ascending”。 注意,名字

和嵌套语法匹配各自的JSTL EL表达式,例如“myModelAttr.pageSize”和

“myModelAttr.sort.ascending”。
 其实,就是用来提供给表现分页用的。

2.  org.springframework.beans.factory.InitializingBean
  这是一个能够被bean实现的接口,如果这个bean需要一旦它所有的属性被注入(还有指定的

BeanFactoryAware和ApplicationContextAware接口相关的方法都被执行)后就做出反应:例如,执行一

个自定义的初始化,或者仅仅是检查所有托管的属性是否被正确的注入。可以通过抛出异常阻止继续初

始化。
 我们也可以选择指定一个自定义的 init-method来代替实现InitializingBean,这个init-

method通过一个描述bean定义的XML定义。
 
3. org.springframework.aop. AfterReturningAdvice
After returning advice 仅仅在正常的方法返回后调用,而不是在抛出异常时调用。这个通知能够看到

返回值,但是不能改变它。
它唯一的方法为:void afterReturning(Object returnValue, Method method, Object[] args,

Object target) throws Throwable;
  在指定的方法(其实就是JoinPoint)成功返回后被调用。
  参数 returnValue: 指定的方法的返回值。
  参数 method:被调用的方法。
  参数 args:方法的参数。
  参数 target:方法期待的目标。可以使null。JoinPoint所在的对象。
  @throws :如果当前对象希望中断调用,则抛出异常。所有方法签名中允许抛出的异

常将会返回给调用者。否则将会被包装为运行期异常。

4.  org.springframework.mail.SimpleMailMessage
设计一个简单mail 信息,它包括收信人mail、发信人mail、主题和内容。
 考虑JavaMailSender 和 JavaMailMimeMessage 来创建更复杂的信息,例如带有附件的信息,

特殊符号,或者私人邮件。
5.  org.springframework.samples.jpetstore.domain.logic. PetStoreImpl
 这里是该程序的作者对其说明,很有意义。
 JPetStore主要业务对象。
这个对象使用了5个DAO对象,从具体的操作持久化API工作中解脱出来。因此,虽然这个程序使用

iBATIS 做数据访问,但是如果要使用其它的持久化工具来访问,就不需要修改这个类的任何代码。
这个对象使用DAO实例是通过Spring容器依赖注入的(使用依赖注入使DAO变成是可配置的)。我们这里使

用的setter注入,暴露每个DAO的setter方法给用户。这就意味着我们只要在配置该类的bean时,使用“

property”属性就可以注入DAO。这里的属性是只写的(write-only):相应的setter方法没有对应的

getter方法。Getter方法是可选的:只有当你的业务对象需要访问这些属性时,才去暴露getter方法。
 在JPetStore程序中只有一个该类的对象。在Spring术语中,这叫做一个“singleton“(单例)

对象。这就意味着每个程序上下文都只有一个。工厂创建一个单例对象;在这里没有必要提供一个私有

的构造器,静态工厂方法等是单例模式的传统实现方式。
 这是一个POJO(普通的Java对象,自我维护自身的状态,处理本身的属性及存取方法外,一般不

提供任何API)。它不依赖于任何的Spring API。在Spring容器外,仍然可用,而且能够在使用JUnit 测

试时,初始化该对象。但是,我们仍然使用声明式事务管理,而依赖Spring的AOP。
 这个类给每个方法定义了一个默认的事务属性。
 注意,这个属性定义仅仅在使用Commons Attribute auto-proxying (即使用Common Attribute

或 Annotation时, Annotation是Spring提供的API,所以依赖了Spring API或Common Attribute API)

时才是必须使用的。
在 war/WEB-INF 目录下的默认applicationContext.xml 文件中的TransactionFactoryProxyBean不需要

定义attributes。
而在接下来使用Commons Attributes attribute 语法来定义的attribute。

6. org.springframework.orm.ibatis.support.SqlMapClientDaoSupport
给iBATIS SqlMapClientDAO提供的方便的父类。需要设置一个SqlMapClient,提供给子类一个基于设入

的SqlMapClient的SqlMapClinetTemplate。
你也可以传递一个已经配置好的SqlMapClientTemplate实例来代替传递一个SqlMapClient(也就是代替默

认的SqlMapClientTemplate,默认的SqlMapClientTemplate使用了传入的SqlMapClient)。这样就使得你

所有的DAO的分享同一个SqlMapClientTemplate配置,例如,一个自定义的SQLExceptionTranslator也可

以使用这个SqlMapClientTemplate。

7.  org.springframework.orm.ibatis.SqlMapClientTemplate
 一个帮助类,用来简化使用iBATIS com.ibatis.sqlmap.client.SqlMapClient API进行数据访

问,依照org.springframework.dao 异常模型,将被检查性异常SQLExceptions转换成不受检测异常

DataAccessExceptions。使用和org.springframework.jdbc.core.JdbcTemplate相同的

org.springframework.jdbc.support.SQLExceptionTranslator机制。
 这个类的主要方法执行了数据访问行为的回调。此外,该类提供了众多的方法去镜像

com.ibatis.sqlmap.client.SqlMapExecutor的执行方法。
 这个模版一般都使用了方便而简单的方法去执行 query/insert/update/delete 操作。但是,

更复杂的操作例如批量更新,就必须自定义一个SqlMapClientCallback,常常都是使用匿名的内部类实

现。例如:
getSqlMapClientTemplate().execute(new SqlMapClientCallback() {
   public Object doInSqlMapClient(SqlMapExecutor executor) throws SQLException {
    executor.startBatch();
    executor.update("insertSomething", "myParamValue");
    executor.update("insertSomethingElse", "myOtherParamValue");
    executor.executeBatch();
    return null;
   }
 });
 这个模版需要一个SqlMapClient来工作,可以通过”sqlMapClient”属性来传递。一个Spring

上下文都典型地使用一个SqlMapClientFactoryBean去构建SqlMapClient。模版还需要配置一个

DataSource来取得连接,但是,如果在传入的SqlMapClient中指定了DataSource(典型地,使用

SqlMapClientFactoryBean的”dataSource”属性),那么这不是必须的。
 所谓的回调就是指,一个对象通过调用另一个对象的方法来完成既定的行为(也可以说是委托

给另一个对象来完成),而本对象可以去执行其它的操作。
8.  org.springframework.samples.jpetstore.web.struts. BaseAction
 JPetStore的Web层的所有Struts Action的父类
从ServletContext中获得WebApplicationContext,然后又从WebApplicationContext中获得

PetStoreFacade,然后通过一个getter方法提供给子类。(或者是继承Spring提供的ActionSupport类,

它预实现了WebApplicatinContext的查找)但是这里在Struts中插入了Spring的API。所以增加了耦合度

,该Action类及其子类不能脱离Spring使用,这里并不是最佳实践。
比较好的方式是:配置Spring将Action作为Bean托管,使用ContextLoaderPlugin,并在Spring context


 * 中设置依赖关系。具体看Spring手册。

9. org.springframework.util.StringUtils
String工具方法的混合类。
主要在Spring框架内工作;请参考Jakarta's Commons Lang 来了解更多而全面的String 工具类的信息


这个提供了一些处理core Java String 和 StringBuffer的简单功能,例如替换一个目标字符串中所有

给定的子字符串的功能。它也提供易使用的方法去转换定界字符串,如CSV字符串,和集合以及数组。
关于持久层DAO接口的好处(个人想法)
 事实上,在程序中有很多对象依赖了DAO,如果我们直接使用DAO,而不是使用DAO的接口的话,

那么如果我们改变底层的数据库时(或者是不同的ORM框架),相关的依赖该DAO的对象的类,或者配置

必须修改。例如,我们使用AOP可配置编程时,我们就必须修改织入的DAO,而如果我们使用DAO接口,我

们可以直接织入到接口上,那么我们不需要修改任何代码。业务层和持久层也应该通过接口通信。
 同样,DAO接口也获得所有接口必将获得的好处,那么就是耦合度的下降。
 具体来说就是,避免其它API的污染,增加API维护和使用的复杂性;另外就是提供给一个更灵

活的多态实现,也就是说在我们无法修改源码的情况下,也能改变具体实现,而且我们应该总是避免,

因为我们常常没有这样的权限,那么就要就API的设计者提供更好的实现(开--闭原理),这里是通过

XML配置文件的方式。
 但是显然,这里增加了间接性,增加了代码量,似乎增加了复杂性,然而恰恰相反,合理的使

用接口使得程序的结构更加的清晰。
 JPetStore使用了SecureBaseAction 主要是提供了当HttpSession中未包含登陆信息时,跳到登

陆页面,其实所有扩展了这个类的类的实例,都是需要在安全条件下(用户权限控制)使用的,其实我们

可以用filter代替。但是这样显然效率更高,但是耦合度也更高了,因为我们不可以配置自己的安全策

略了。
 JPetStore在Struts Web控制代码中使用了大量的Spring API,其实这是不推荐使用的,例如,

BaseAction中使用了WebApplicationContext;SearchProductsAction使用了

org.springframework.util.StringUtils,还有使用很频繁的

org.springframework.beans.support.PagedListHolder。
 JPetStore在使用Struts时,大量使用了HttpSession,好的建议是尽量少使用HttpSession,所

以这里也不是好的实践,例如,将所有的页面都找出来,但是是缓存在HttpSession中,虽然提高了客户

端的用户感受,但是会给服务器以沉重的负担。
 JPetStore中将ActionForm做了两种作用,一种主要是用于数据的提交(Form中用),一般以

working开头,一种主要用于处理过后的数据的显示和数据的保存。因为都是存储在HttpSession中,为

了区分采用了不同的名字,而working FormBean的生命周期是在提交了数据后结束,因此在这时,我们

应该将内存空间收回。

posted on 2009-11-04 21:16 vagasnail 阅读(761) 评论(0)  编辑  收藏 所属分类: Java Web


只有注册用户登录后才能发表评论。


网站导航: