使用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式的感觉啊?赶快来试试吧

你可能感兴趣的:(java,spring,Web,jpa,Rails)