`
herowzz
  • 浏览: 19517 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

使用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命令,我们可以很快的了解各种操作提示

首先,设置数据库
install jpa -provider HIBERNATE -database MYSQL

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

然后新建一个domain
new persistent class jpa -name ~.domain.Employee -testAutomatically


这时roo会帮我们生成Employee类,这时Employee类还没有任何字段,我们可以通过roo shell往里面加入一些字段

add field string -fieldName name -notNull -sizeMax 200
add field date jpa -fieldName birth -type java.util.Date
......


最终生成的Employee如下:
@Entity
@RooEntity
@RooJavaBean
@RooToString
public class Employee {

    @NotNull
    @Size(max = 200)
    private String name;

    @Temporal(TemporalType.TIMESTAMP)
    private Date birth;
}


你会发现,怎么没有get set呢?我们反编译看下编译后的class代码
// Decompiled by DJ v3.5.5.77 Copyright 2003 Atanas Neshkov  Date: 2009-8-8 21:37:43
// Home Page : http://members.fortunecity.com/neshkov/dj.html  - Check often for new version!
// Decompiler options: packimports(3) 
// Source File Name:   Employee.java

package com.javaeye.domain;

import java.util.Date;
import java.util.List;
import javax.persistence.EntityManager;
import org.aspectj.runtime.reflect.Factory;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.beans.factory.aspectj.*;

// Referenced classes of package com.javaeye.domain:
//            Employee_Roo_ToString, Employee_Roo_Entity, Employee_Roo_JavaBean

public class Employee
    implements ConfigurableObject
{

    public Employee()
    {
        org.aspectj.lang.JoinPoint joinpoint1 = Factory.makeJP(ajc$tjp_1, this, this);
        org.aspectj.lang.JoinPoint joinpoint = Factory.makeJP(ajc$tjp_0, this, this);
        if(this != null && getClass().isAnnotationPresent(org/springframework/beans/factory/annotation/Configurable) && AnnotationBeanConfigurerAspect.ajc$if_1((Configurable)getClass().getAnnotation(org/springframework/beans/factory/annotation/Configurable)))
            AnnotationBeanConfigurerAspect.aspectOf().ajc$before$org_springframework_beans_factory_aspectj_AbstractDependencyInjectionAspect$1$e854fa65(this);
        if(this != null && getClass().isAnnotationPresent(org/springframework/beans/factory/annotation/Configurable) && (this == null || !getClass().isAnnotationPresent(org/springframework/beans/factory/annotation/Configurable) || !AnnotationBeanConfigurerAspect.ajc$if_1((Configurable)getClass().getAnnotation(org/springframework/beans/factory/annotation/Configurable))) && AbstractDependencyInjectionAspect.ajc$if_0(joinpoint))
            AnnotationBeanConfigurerAspect.aspectOf().ajc$afterReturning$org_springframework_beans_factory_aspectj_AbstractDependencyInjectionAspect$2$1ea6722c(this);
        Employee_Roo_Entity.ajc$interFieldInit$com_javaeye_domain_Employee_Roo_Entity$com_javaeye_domain_Employee$entityManager(this);
        Employee_Roo_Entity.ajc$interFieldInit$com_javaeye_domain_Employee_Roo_Entity$com_javaeye_domain_Employee$id(this);
        Employee_Roo_Entity.ajc$interFieldInit$com_javaeye_domain_Employee_Roo_Entity$com_javaeye_domain_Employee$version(this);
        if(!AnnotationBeanConfigurerAspect.ajc$if_1((Configurable)getClass().getAnnotation(org/springframework/beans/factory/annotation/Configurable)) && AbstractDependencyInjectionAspect.ajc$if_0(joinpoint1))
            AnnotationBeanConfigurerAspect.aspectOf().ajc$afterReturning$org_springframework_beans_factory_aspectj_AbstractDependencyInjectionAspect$2$1ea6722c(this);
    }

    public static String ajc$privFieldGet$com_javaeye_domain_Employee_Roo_JavaBean$com_javaeye_domain_Employee$name(Employee employee)
    {
        return employee.name;
    }

    public static void ajc$privFieldSet$com_javaeye_domain_Employee_Roo_JavaBean$com_javaeye_domain_Employee$name(Employee employee, String s)
    {
        employee.name = s;
    }

    public static Date ajc$privFieldGet$com_javaeye_domain_Employee_Roo_JavaBean$com_javaeye_domain_Employee$birth(Employee employee)
    {
        return employee.birth;
    }

    public static void ajc$privFieldSet$com_javaeye_domain_Employee_Roo_JavaBean$com_javaeye_domain_Employee$birth(Employee employee, Date date)
    {
        employee.birth = date;
    }

    public static long countEmployees()
    {
        return Employee_Roo_Entity.ajc$interMethod$com_javaeye_domain_Employee_Roo_Entity$com_javaeye_domain_Employee$countEmployees();
    }

    public static EntityManager entityManager()
    {
        return Employee_Roo_Entity.ajc$interMethod$com_javaeye_domain_Employee_Roo_Entity$com_javaeye_domain_Employee$entityManager();
    }

    public static List findAllEmployees()
    {
        return Employee_Roo_Entity.ajc$interMethod$com_javaeye_domain_Employee_Roo_Entity$com_javaeye_domain_Employee$findAllEmployees();
    }

    public static Employee findEmployee(Long long1)
    {
        return Employee_Roo_Entity.ajc$interMethod$com_javaeye_domain_Employee_Roo_Entity$com_javaeye_domain_Employee$findEmployee(long1);
    }

    public static List findEmployeeEntries(int i, int j)
    {
        return Employee_Roo_Entity.ajc$interMethod$com_javaeye_domain_Employee_Roo_Entity$com_javaeye_domain_Employee$findEmployeeEntries(i, j);
    }

    public void flush()
    {
Employee_Roo_Entity.ajc$interMethod$com_javaeye_domain_Employee_Roo_Entity$com_javaeye_domain_Employee$flush(this);
    }

    public Date getBirth()
    {
        return Employee_Roo_JavaBean.ajc$interMethod$com_javaeye_domain_Employee_Roo_JavaBean$com_javaeye_domain_Employee$getBirth(this);
    }

    public Long getId()
    {
        return Employee_Roo_Entity.ajc$interMethod$com_javaeye_domain_Employee_Roo_Entity$com_javaeye_domain_Employee$getId(this);
    }

    public String getName()
    {
        return Employee_Roo_JavaBean.ajc$interMethod$com_javaeye_domain_Employee_Roo_JavaBean$com_javaeye_domain_Employee$getName(this);
    }

    public Integer getVersion()
    {
        return Employee_Roo_Entity.ajc$interMethod$com_javaeye_domain_Employee_Roo_Entity$com_javaeye_domain_Employee$getVersion(this);
    }

    public void merge()
    {   Employee_Roo_Entity.ajc$interMethod$com_javaeye_domain_Employee_Roo_Entity$com_javaeye_domain_Employee$merge(this);
    }

    public void persist()
    {     Employee_Roo_Entity.ajc$interMethod$com_javaeye_domain_Employee_Roo_Entity$com_javaeye_domain_Employee$persist(this);
    }

    public void remove()
    {
        Employee_Roo_Entity.ajc$interMethod$com_javaeye_domain_Employee_Roo_Entity$com_javaeye_domain_Employee$remove(this);
    }

    public void setBirth(Date date)
    {
        Employee_Roo_JavaBean.ajc$interMethod$com_javaeye_domain_Employee_Roo_JavaBean$com_javaeye_domain_Employee$setBirth(this, date);
    }

    public void setId(Long long1)
    {
        Employee_Roo_Entity.ajc$interMethod$com_javaeye_domain_Employee_Roo_Entity$com_javaeye_domain_Employee$setId(this, long1);
    }

    public void setName(String s)
    {
        Employee_Roo_JavaBean.ajc$interMethod$com_javaeye_domain_Employee_Roo_JavaBean$com_javaeye_domain_Employee$setName(this, s);
    }

    public void setVersion(Integer integer)
    {
        Employee_Roo_Entity.ajc$interMethod$com_javaeye_domain_Employee_Roo_Entity$com_javaeye_domain_Employee$setVersion(this, integer);
    }

    public String toString()
    {
        return Employee_Roo_ToString.ajc$interMethod$com_javaeye_domain_Employee_Roo_ToString$com_javaeye_domain_Employee$toString(this);
    }

    private String name;
    private Date birth;
    public transient EntityManager ajc$interField$com_javaeye_domain$entityManager;
    public Long ajc$interField$com_javaeye_domain_Employee_Roo_Entity$id;
    public Integer ajc$interField$com_javaeye_domain_Employee_Roo_Entity$version;
    private static final org.aspectj.lang.JoinPoint.StaticPart ajc$tjp_0; /* synthetic field */
    private static final org.aspectj.lang.JoinPoint.StaticPart ajc$tjp_1; /* synthetic field */

    static 
    {
        Factory factory = new Factory("Employee.java", Class.forName("com.javaeye.domain.Employee"));
        ajc$tjp_0 = factory.makeSJP("initialization", factory.makeConstructorSig("1", "org.springframework.beans.factory.aspectj.ConfigurableObject", "", "", ""), 17);
        ajc$tjp_1 = factory.makeSJP("initialization", factory.makeConstructorSig("1", "com.javaeye.domain.Employee", "", "", ""), 17);
    }
}


经过反编译生成的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了,同样是一条语句
new controller automatic -formBackingObject ~.domain.Employee -name ~.web.CommentController


你会发现,EmployeeController,spring mvc的配置以及curd的jsp页面全部生成了

EmployeeController代码如下:
@RooWebScaffold(automaticallyMaintainView = true, formBackingObject = Employee.class)
@RequestMapping("/employee/**")
@Controller
public class EmployeeController {
}


在这里出现了一行@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式的感觉啊?赶快来试试吧!







分享到:
评论
22 楼 fjjiaboming 2011-12-27  
很强大.
思想啊.
21 楼 Angel_Night 2010-07-06  
herowzz 写道
其实东西还是spring的那套东西,引擎就是aspect
不过使用这个引擎之后,立马就变为了充血模型,开发方式都改变了
可见spring的这招很妙,可能有人会觉得小儿科,但是为什么都是人家发明了新东西,新思想,而我们却在这里除了会说“雕虫小技”,还会什么?


ajax刚出来的时候很多人认为雕虫小技都不算吧。。
20 楼 binarier 2010-05-12  
这里有一点刚接触时都会忽略的,就是加字段不需要一个个地add field,只要修改Entity,在ROO保持打开的情况下,那些aspectJ 的 ITD会实时生成的。
19 楼 xuyangcn 2010-04-29  
刚刚试了一下,发现对于基本的CRUD确实不错,但是我试图整合JQuery的Plugin不成功,没有出错信息。无语啊。
18 楼 herowzz 2010-01-19  
Kymair 写道
liujunsong 写道
批评两句.雕虫小极而已.

也许这么做开始的时候能省点力气.可是等到一年以后你来维护这些代码的时候,是不是还能象现在这么高兴呢?想想这个问题吧,如果答案是否定的,那么就趁早放弃吧.


其实这是一种程序员常有的误区

问题是,你如果比较好的掌握了它,你根本就不需要再去看生成后的代码,除非是库本身有BUG。这种可能性不排除,也许你会说,到时候调试查错困难,但是相对于它给你减少的代码和工作量从而提高的效率,从而减少的潜在BUG,比因它自己可能的BUG给你带来的阻碍,应该更多吧?
软件开发就是这种方向,复杂性越来越高,只能抽象等级也越来越高。


调试查错也不可能困难,生成的代码都在你手上,你想调试就调试,想改就改
除非一种可能,就是那位仁兄根本就看不懂,不会。如果连spring都不懂,不会的话,那讨论的重点就不在roo上了,而是spring适不适合他了...
17 楼 Kymair 2010-01-19  
liujunsong 写道
批评两句.雕虫小极而已.

也许这么做开始的时候能省点力气.可是等到一年以后你来维护这些代码的时候,是不是还能象现在这么高兴呢?想想这个问题吧,如果答案是否定的,那么就趁早放弃吧.


其实这是一种程序员常有的误区

问题是,你如果比较好的掌握了它,你根本就不需要再去看生成后的代码,除非是库本身有BUG。这种可能性不排除,也许你会说,到时候调试查错困难,但是相对于它给你减少的代码和工作量从而提高的效率,从而减少的潜在BUG,比因它自己可能的BUG给你带来的阻碍,应该更多吧?
软件开发就是这种方向,复杂性越来越高,只能抽象等级也越来越高。
16 楼 tanbamboo 2010-01-15  
通过Aspect-J来做这些,我觉得相当不错的,起码是预编织的,比动态的性能肯定要好。
另外通过annotation方式做scaffold的话,也比rails的方式方便,起码后期改动要方便。
不知道如果要override CRUD中某个方法,是不是很方便。
有空尝试一下。

Grails小小的试用了一下,个人感觉不好,与rails的差距比较大,尤其是命令脚步执行那个慢啊。
15 楼 herowzz 2010-01-15  
Ben Alex 写道

ROO框架使用Aspect来描述像@Configurable这样的注解。在Roo框架中使用AOP背后的理由是什么?

至于为什么我们使用aspect作为Java代码生成的基础,背后有许多动机,我在我的系列博文的第三部分谈到了这一内容。但是实质上我提供了一些不同的备选技术原型,包括JSR 269、构建时生成源代码、IDE插件、开发时产生字节码、运行时产生字节码以及高级反射方法如扩展Spring Framework AOP、DSL等等。

我优先要考虑的事情是确保:
就算用户停止使用这一工具,他们的项目照样能够进行;这直接就排除了采取任何运行时动作的可能性。
在运行时,用户的项目必须不以牺牲性能为代价;这直接排除了大多数反射方法的可能性。
开发者要能够使用他们已有的Java知识、技巧和经历。于是工具必须支持常规Java编程体验、支持开发者的普通编程形式、使他们可以使用自己常用的IDE,访问熟悉的工具如debugger和代码助手。该工具必须能使开发者运用已知、已理解及所期望的东西。这样就排除了任何特定的字节码方法以及大多数运行时方法。
该工具必须能自动工作,并且不需要明确调用,也不需要系统集成或建造特定IDE。它必须绝对支持透明的、即时的round-tripping。这就排除了JSR 269以及构创建于系统等方法,比如类似于XDoclet的工具。
其次要考虑:
用户的项目必须工作于Java 5及更高版本上。这就排除了JSR 269,将其排除的原因还有很多(比如原型时期脆弱的IDE支持)。
该工具应该容易让最终用户进行扩展。当然,由于我们使用了AspectJ技术,这是件非常容易的事。它还不鼓励使用任何特定IDE的技术,这可能比Roo附加组件需要更复杂的开发和部署过程。
该工具对增加附加组件的支持应该是长期的。使用AspectJ ITD提供的分离概念可以很容易的实现这一点。
该工具应该非常轻量级:下载、学习、运转都应非常迅速。这对一个拥有最少依赖的基于shell的方法非常有利。Roo 下载文件小于3M!
实质上AspectJ ITDs增加了一个自动维护的元数据模型,它是我们能找到的唯一解决方案,可以满足所有需求。当然,如果你愿意牺牲一些表达方面的要求的话,自然会有其他方法解决这一问题。


14 楼 herowzz 2010-01-15  
其实东西还是spring的那套东西,引擎就是aspect
不过使用这个引擎之后,立马就变为了充血模型,开发方式都改变了
可见spring的这招很妙,可能有人会觉得小儿科,但是为什么都是人家发明了新东西,新思想,而我们却在这里除了会说“雕虫小技”,还会什么?
13 楼 魔力猫咪 2010-01-15  
“怀旧玩家的支持”?又不是老游戏换个引擎出XX版。
12 楼 herowzz 2010-01-15  
魔力猫咪 写道
感觉是Grails把Groovy的外壳剥了就是roo了。

恩,确实,第一次使用roo的时候就有种grails的感觉,不过roo基于spring之上,使用java原生语言,与动态语言相比的性能优势,必然会获得很多怀旧玩家的支持。。。
11 楼 herowzz 2010-01-15  
在雏形的基础上进行修改,增加完全没有问题
用AspectJ插件可以很简单的将aj文件push in到类文件里
还可以直接对aj文件进行修改
10 楼 魔力猫咪 2010-01-15  
感觉是Grails把Groovy的外壳剥了就是roo了。
9 楼 grandboy 2010-01-15  
liujunsong 写道
批评两句.雕虫小极而已.

也许这么做开始的时候能省点力气.可是等到一年以后你来维护这些代码的时候,是不是还能象现在这么高兴呢?想想这个问题吧,如果答案是否定的,那么就趁早放弃吧.


这个东西现在还不成熟,只是1.0 release. 我不知道ror的开发过程是什么样的,请有这方面经验的讲一下。我是想用它先做一个雏形,把一些基础代码都生成,在此基础上进行修改,增加功能。可能我用得不好,好像不太适合我这种需求。
8 楼 herowzz 2010-01-15  
liujunsong 写道
批评两句.雕虫小极而已.

也许这么做开始的时候能省点力气.可是等到一年以后你来维护这些代码的时候,是不是还能象现在这么高兴呢?想想这个问题吧,如果答案是否定的,那么就趁早放弃吧.


那请赐教一下,跟您自己手写的代码相比,哪里不好维护了?
7 楼 liujunsong 2010-01-14  
批评两句.雕虫小极而已.

也许这么做开始的时候能省点力气.可是等到一年以后你来维护这些代码的时候,是不是还能象现在这么高兴呢?想想这个问题吧,如果答案是否定的,那么就趁早放弃吧.
6 楼 Arden 2010-01-14  
关键是开发的时候修改东西要不要重启Web服务器!!
5 楼 grandboy 2010-01-14  
我昨天晚上试一下这个工具,如果能支持数据库就好了,要不然一条一条命令来加Field,还是挺麻烦的。希望它下一版本能加上这个功能。
4 楼 zspzlxn 2009-11-06  
一切皆有可能
3 楼 zspzlxn 2009-11-06  
太强了。。。领教了。。这种手法还是第一次看到

相关推荐

    Spring Roo 简介,第 4 部分: 用 Spring Roo 和 Cloud Foundry 在云中快速开发应用程序

    在本篇文章中,我们将深入探讨 Spring Roo 的使用,以及如何结合 Cloud Foundry 进行云端应用开发。Spring Roo 是一个基于 Java 的开源工具,它简化了 Spring 应用程序的构建过程,通过自动化任务和代码生成,让...

    spring roo使用文档

    - **IDE 集成**:将 Spring Roo 与 IDE 结合使用以提升开发体验。 - **创建 Web 层**:为应用添加前端交互能力。 - **部署与安全**:介绍如何部署应用并实现基本的安全措施。 #### 六、应用架构概述 - **整体...

    Spring Roo In Action

    标题《Spring Roo In Action》意味着这本书是一本实用指南,旨在向读者展示如何使用Spring Roo来开发实际的Java应用程序。从描述中可以得知,本书是Manning出版社出版的完整版,它可能包含了Spring Roo的基本概念、...

    spring roo in action

    书中还涉及了Web开发部分,探讨了如何使用Spring Roo快速搭建Web应用程序,包括使用Spring MVC进行控制器和视图层的快速开发。Spring Roo的Web开发支持包括了多种Web层技术,方便开发者根据项目需求选择合适的技术...

    Spring ROO

    在开始使用Spring ROO之前,你需要确保你的开发环境已经准备就绪。首先,你需要安装Java Development Kit (JDK)。JDK是Java编程的基础,它包含了编译器、Java运行时环境以及其他必要的工具。确保你的JDK版本与Spring...

    Spring Roo命令文档

    Spring Roo是Spring框架的一部分,它提供了一种快速开发工具,帮助开发者在Java应用中创建和管理代码。Roo通过自动化过程,简化了常见的开发任务,如设置项目结构、创建实体类、生成数据库表映射以及创建CRUD操作。...

    spring roo 1.1.3 学习资料

    Spring Roo是Spring框架家族中的一个创新工具,旨在简化Java应用程序的开发过程,特别是企业级应用。它基于Spring的模块化架构,提供了一种快速开发、自动化代码生成和最佳实践集成的解决方案。Spring Roo 1.1.3是该...

    springroo快速学习

    SpringRoo是Spring框架的扩展,它使用命令行界面(CLI)或集成开发环境(IDE)插件来提供代码生成和自动化功能。它的目标是简化Java应用程序的构建过程,特别适合于Spring Boot应用的早期开发阶段。 二、安装与设置...

    spring-roo-1.1.5.RELEAS

    Spring Roo是Spring框架家族中的一个开发工具,它旨在加速Java应用程序的开发过程,特别是通过提供命令行接口和集成开发环境(IDE)插件来简化常见的编程任务。标题"spring-roo-1.1.5.RELEASE"指的是Spring Roo的一...

    spring roo 生成数据库表

    Spring Roo是Spring框架家族中的一个工具,用于加速Java开发,特别是企业级应用的构建。它通过命令行界面或集成开发环境(IDE)插件提供了一种快速开发的方式,可以帮助开发者生成代码、设置依赖和配置,使得开发...

    SpringRoo 官方文档-版本 2.0.0.RC1

    SpringRoo 是一款由 Pivotal Software(现为 VMware 的一部分)开发的快速应用开发工具。它旨在帮助开发者简化基于Spring框架的应用程序构建过程。SpringRoo 通过提供一系列自动化代码生成功能,允许开发者在几分钟...

    spring-roo-1.3.2.zip

    Spring Roo是Spring框架家族中的一个开发工具,它旨在加速Java应用程序的开发过程,特别是通过自动化常见任务和提供代码生成功能。Spring Roo 1.3.2是该工具的一个版本,其发布版本为RELEASE,意味着它是稳定且可供...

    spring-roo-2.0.0.RC1.zip

    Spring Roo是Spring框架家族中的一个开源工具,旨在简化Java应用程序的开发过程,特别是Spring MVC和Spring Data应用。这个"spring-roo-2.0.0.RC1.zip"压缩包包含的是Spring Roo的2.0.0 Release Candidate 1版本,这...

    os-springroo2-sample_code

    【os-springroo2-sample_code】项目是一个关于Spring Roo的示例代码库,它展示了如何使用Spring Roo框架来快速开发应用程序。Spring Roo是Spring框架的一部分,它提供了一种简化和加速Java应用开发的方式,通过自动...

    spring-roo-docs

    - **更高生产力:** 使用SpringRoo可以显著减少开发时间,因为它提供了一系列自动化工具来生成代码模板。 - **标准Java实践:** SpringRoo遵循Java的最佳实践,这意味着生成的应用程序符合行业标准。 - **易于学习和...

    Spring Roo - Reference Documentation

    本文将深入剖析Spring Roo的关键特性和使用流程,帮助读者理解如何利用这一工具提高开发速度,同时确保代码质量和可维护性。 #### 1.1 Spring Roo的核心价值:更高生产力 Spring Roo通过其独特的命令行接口(CLI)...

    Spring Roo 简介

    使用 Spring Roo 开发应用程序涉及以下几个步骤: 1. **初始化项目**:使用 `roo new` 命令创建一个新的 Spring Roo 项目。 2. **添加实体**:使用 `entity` 命令创建数据库实体。 3. **定义字段**:使用 `field` ...

    spring-roo-1.1.0.M1.zip_54587.m1_M1 ssh_Spring Roo download_spri

    Spring Roo是Spring Framework的一个附加工具,它为Java开发者提供了一个快速开发平台,旨在简化和加速应用程序的构建过程。"spring-roo-1.1.0.M1.zip_54587.m1_M1 ssh_Spring Roo download_spri"这个标题暗示了这是...

    spring roo action

    ### Spring Roo Action: 加速开发流程的利器 #### 引言 随着软件开发技术的不断发展,开发者们一直在寻求更高效、更便捷的方式来构建高质量的应用程序。Spring Roo 正是为了解决这一需求而诞生的。它是一种快速应用...

Global site tag (gtag.js) - Google Analytics