`

使用Spring Roo ,感受ROR式的开发

阅读更多

 

Roo是一种 Spring 开发的辅助工具,使用命令行操作来生成自动化项目,操作非常类似于rails 

我这里使用spring tool suit来开发一个demo项目 

首先新建个spring template project,然后选择template类型为Roo Wep App (based on Roo 1.0.0.RC1) 
这样,便会通过roo的命令自动生成一个标准的maven web项目,里面含有最基本的Spring 配置 

建好项目后,我们可以在project上运行roo shell。 通过hint命令,我们可以很快的了解各种操作提示 

首先,设置数据库 
Roo shell代码  
  1. install jpa -provider HIBERNATE -database MYSQL  

roo会帮你在配置文件applicationContext.xml中配置好了相应的数据源配置,并且在 pom.xml中已经添加jpa和数据库驱动等相关的依赖。 

然后新建一个domain 
Roo shell代码  
  1. new persistent class jpa -name ~.domain.Employee -testAutomatically  

这时roo会帮我们生成Employee类,这时Employee类还没有任何字段,我们可以通过roo shell往里面加入一些字段 
Roo shell代码  
  1. add field string -fieldName name -notNull -sizeMax 200  
  2. add field date jpa -fieldName birth -type java.util.Date  
  3. ......  

最终生成的Employee如下: 
Java代码  
  1. @Entity  
  2. @RooEntity  
  3. @RooJavaBean  
  4. @RooToString  
  5. public class Employee {  
  6.   
  7.     @NotNull  
  8.     @Size(max = 200)  
  9.     private String name;  
  10.   
  11.     @Temporal(TemporalType.TIMESTAMP)  
  12.     private Date birth;  
  13. }  
你会发现,怎么没有get set呢?我们反编译看下编译后的class代码 。
经过反编译生成的class发现,通过domain类上面的roo注释,自动在类编译时加入get set,甚至我们发现了findAllEmployees,persist,remove,哈,这不是我们梦寐以求的充血模型吗? 

原来,roo在为我们创建domain的时候自动为同一个domain创建了4个aspect(.aj files),并在编译期动态为domain切入代码. 
4个aspect分别是: 
domainName_Roo_Configurable.aj(配置) 
domainName_Roo_Entity.aj(加入orm持久) 
domainName_Roo_JavaBean.aj(为字段生成get set) 
domainName_Roo_ToString.aj(重写toString) 

可见,使用roo我们彻底摆脱了在daomain里对各个属性写get set,并且使domain摇身一变为充血。 

下一步,就是建Controller了,同样是一条语句 
Roo shell代码  
  1. new controller automatic -formBackingObject ~.domain.Employee -name ~.web.CommentController  
你会发现,EmployeeController,spring mvc的配置以及curd的jsp页面全部生成了 
EmployeeController代码如下: 
Java代码  
  1. @RooWebScaffold(automaticallyMaintainView = true, formBackingObject = Employee.class)  
  2. @RequestMapping("/employee/**")  
  3. @Controller  
  4. public class EmployeeController {  
  5. }  
在这里出现了一行@RooWebScaffold注解,做过rails的人会想,这不是rails里面的scaffold吗?没错,通过@RooWebScaffold注解,EmployeeController自动获得了curd的所有功能。 

同样是生成controllerName_Roo_Controller.aj在编译期织入代码 

我们来看看生成的EmployeeController_Roo_Controller.aj: 
package com.javaeye.web;   
   
privileged aspect EmployeeController_Roo_Controller {   
       
    @org.springframework.web.bind.annotation.RequestMapping(value = "/employee", method = org.springframework.web.bind.annotation.RequestMethod.POST)       
    public java.lang.String EmployeeController.create(@org.springframework.web.bind.annotation.ModelAttribute("employee") com.javaeye.domain.Employee employee, org.springframework.validation.BindingResult result) {       
        if (employee == null) throw new IllegalArgumentException("A employee is required");           
        for(javax.validation.ConstraintViolation<com.javaeye.domain.Employee> constraint : javax.validation.Validation.buildDefaultValidatorFactory().getValidator().validate(employee)) {           
            result.rejectValue(constraint.getPropertyPath(), null, constraint.getMessage());               
        }           
        if (result.hasErrors()) {           
            return "employee/create";               
        }           
        employee.persist();           
        return "redirect:/employee/" + employee.getId();           
    }       
       
    @org.springframework.web.bind.annotation.RequestMapping(value = "/employee/form", method = org.springframework.web.bind.annotation.RequestMethod.GET)       
    public java.lang.String EmployeeController.createForm(org.springframework.ui.ModelMap modelMap) {       
        modelMap.addAttribute("employee", new com.javaeye.domain.Employee());           
        return "employee/create";           
    }       
       
    @org.springframework.web.bind.annotation.RequestMapping(value = "/employee/{id}", method = org.springframework.web.bind.annotation.RequestMethod.GET)       
    public java.lang.String EmployeeController.show(@org.springframework.web.bind.annotation.PathVariable("id") java.lang.Long id, org.springframework.ui.ModelMap modelMap) {       
        if (id == null) throw new IllegalArgumentException("An Identifier is required");           
        modelMap.addAttribute("employee", com.javaeye.domain.Employee.findEmployee(id));           
        return "employee/show";           
    }       
       
    @org.springframework.web.bind.annotation.RequestMapping(value = "/employee", method = org.springframework.web.bind.annotation.RequestMethod.GET)       
    public java.lang.String EmployeeController.list(org.springframework.ui.ModelMap modelMap) {       
        modelMap.addAttribute("employees", com.javaeye.domain.Employee.findAllEmployees());           
        return "employee/list";           
    }       
       
    @org.springframework.web.bind.annotation.RequestMapping(method = org.springframework.web.bind.annotation.RequestMethod.PUT)       
    public java.lang.String EmployeeController.update(@org.springframework.web.bind.annotation.ModelAttribute("employee") com.javaeye.domain.Employee employee, org.springframework.validation.BindingResult result) {       
        if (employee == null) throw new IllegalArgumentException("A employee is required");           
        for(javax.validation.ConstraintViolation<com.javaeye.domain.Employee> constraint : javax.validation.Validation.buildDefaultValidatorFactory().getValidator().validate(employee)) {           
            result.rejectValue(constraint.getPropertyPath(), null, constraint.getMessage());               
        }           
        if (result.hasErrors()) {           
            return "employee/update";               
        }           
        employee.merge();           
        return "redirect:/employee/" + employee.getId();           
    }       
       
    @org.springframework.web.bind.annotation.RequestMapping(value = "/employee/{id}/form", method = org.springframework.web.bind.annotation.RequestMethod.GET)       
    public java.lang.String EmployeeController.updateForm(@org.springframework.web.bind.annotation.PathVariable("id") java.lang.Long id, org.springframework.ui.ModelMap modelMap) {       
        if (id == null) throw new IllegalArgumentException("An Identifier is required");           
        modelMap.addAttribute("employee", com.javaeye.domain.Employee.findEmployee(id));           
        return "employee/update";           
    }       
       
    @org.springframework.web.bind.annotation.RequestMapping(value = "/employee/{id}", method = org.springframework.web.bind.annotation.RequestMethod.DELETE)       
    public java.lang.String EmployeeController.delete(@org.springframework.web.bind.annotation.PathVariable("id") java.lang.Long id) {       
        if (id == null) throw new IllegalArgumentException("An Identifier is required");           
        com.javaeye.domain.Employee.findEmployee(id).remove();           
        return "redirect:/employee";           
    }       
       
    @org.springframework.web.bind.annotation.InitBinder       
    public void EmployeeController.initBinder(org.springframework.web.bind.WebDataBinder binder) {       
        binder.registerCustomEditor(java.util.Date.class, new org.springframework.beans.propertyeditors.CustomDateEditor(new java.text.SimpleDateFormat("yyyy-M-d"), false));           
    }       
       
}  
 这样,Controller里不用写一行代码,就自动拥有了curd,而且,最新的roo使用了spring3.0,还支持了rest 

好了,就这么简单,一个domain,一个Controller,我们就可以发布到tomcat中运行了。 
不到5分钟,我们就可以生成了一个可运行的项目,是不是很有ror式的感觉啊?赶快来试试吧
分享到:
评论
1 楼 pengain 2012-05-18  

相关推荐

Global site tag (gtag.js) - Google Analytics