Spring 2.5新特性带来的便捷与一点疑问

来源:互联网 发布:oracle和mysql的转换 编辑:程序博客网 时间:2024/04/26 13:29
 Spring 2.5相对于2.0来说,最大的特性在于极尽可能的降低了配置文件的数量(大范围的使用@Anotation),并对配置能够做到尽可能在启动装载配置时进行校验,这样之前对于配置文件的遗漏等问题在第一时间就能够检测出来。 当然Spring 2.5其他很多特性比较隐形,譬如多线程性能的提升等等。

在Spring 2.5刚发布没几天,我就通过一个项目进行了2.0向2.5的迁移,在这期间深刻的感受到了2.5带了的便捷,但在进行Spring MVC的配置时,对新出的2.5的FormController存有深深的疑问。

为了实例方便,使用官方源码进行注解提问(spring-framework-2.5/samples/petclinic/src/org/springframework/samples/petclinic/web/EditPetForm.java),先上源码(被部分删减,并做了标识)
@Controller // 新增的Anotation,同时新增的还有@Service,可用于组件扫描
@RequestMapping("/editPet.do")  // 新增的Anotation,简化了HandlerMapping
@SessionAttributes("pet") --------   // 新增的Anotation,自动进行Session属性的存取
public class EditPetForm {

...

@ModelAttribute("types") --------
public Collection<PetType> populatePetTypes() {
return this.clinic.getPetTypes();
}

@RequestMapping(method = RequestMethod.GET) --------
public String setupForm(@RequestParam("petId") int petId, ModelMap model) {
Pet pet = this.clinic.loadPet(petId);
model.addAttribute("pet", pet);
return "petForm";
}

@RequestMapping(method = RequestMethod.POST)
public String processSubmit(@ModelAttribute("pet") Pet pet...) {--------
...
}

}
**************************************************

在图1标注的地方(@SessionAttributes("pet")),实例代码使用session的方式进行缓存了图3标注获得的数据,然后图4标注的地方将使用session中缓存的数据先加载,然后再绑定请求参数(即form表单中的数据)。这是实例代码给我们反映的内容。

对比之前的SimpleFormController,图3标注类似formBackingObject()接口,图2标注类似于referenceData(),图4标注类似于onSubmit()接口。

这些是相似点,但最大的差异在于流程完全不同了。
SimpleFormController的执行顺序基本为,在GET(即进入的时候)的时候,为formBackingObject() --> referenceData()...,在提交的时候formBackingObject() -->...-->onSubmit()。
Spring 2.5的Annotation方式,在GET的时候基本类似,但在提交的时候,缺少了个关键的formBackingObject() 的数据加载,这个在需要提交的时候使用最新的业务数据然后再进行form字段绑定的场合问题尤其突出(你可能会问为啥不用官方代码的session缓存方式,请假设如下应用,编辑一个用户实体,需要操作员修改用户的电话信息,其他信息如这个用户的积分等信息是其他业务产生的,如用户订购了某些商品后自动累积积分。在这种情况下,在操作员编辑用户电话信息的同时,如果这个用户正好在下单购买商品,而且是用户先下单完成,这个时候如果操作员才提交本次编辑,则之前用户下单产生的积分就会回退到操作员打开编辑界面时的积分了(使用的是session啊))。

相信我上面提到的业务场景会有很多,所以目前官方提供的方式在处理这些场合时会显得非常累(你可以在处理方法里面加载最新的用户数据,然后手工将spring绑定的对象中你认为在页面中被操作的字段进行覆盖)。

这个问题不晓得是官方本身提供但因为我看的有所遗漏的缘故还是确实是开发组没有考虑到。