2008-03-06
Warp framework - 一个相当有前途的Java轻量级Web开发框架
关键字: warp
Warp framework 是最近刚刚发布的、基于Google Guice的轻量级Web开发框架,我也是在JavaEye网站的新闻频道看到的这条新闻: warp-persist 1.0: 为Google Guice专门提供持久层与事务处理的框架,通过这个新闻仔细阅读了Warp网站上面的文档,感觉到很振奋,Warp是一个相当棒的Java Web框架,而且前景非常看好。
Warp框架充分利用了JDK5.0的Annotation和泛型机制,并且基于Google Guice这个IoC框架,提供了full-stack的Web开发设施,他主要包含了四个部分:
warp-persist框架:封装Hibernate和JPA,提供事务管理和持久化资源管理
warp-dynamic-finder:提供了基于Annotation的动态查询功能,让数据库查询变得异常简单,不再需要DAO层
warp-mvc:借鉴了Tapestry5,提供了一个基于事件机制和组件化的Web层,并且组件注入方式高度IoC化
warp-servlet: 提供了一些Servlet的封装和附加的高级功能,例如URL过滤,和其他web框架集成等等
这几年来,Java在Web开发框架方面的进步显得很有限,Spring/Hibernate组合对撼JBoss Seam形成两大竞争的主流态势,但是这两个Web框架在Web快速开发方面的创新还显得不够好:Spring是越来越臃肿了,配置文件也是越来越复杂难懂了;JBoss Seam门槛又过高,而且集成的JSF一向受人垢病,并非完美的解决方案,特别是在Ruby on Rails横空出世之后,Java社区对于简洁易用的快速web开发框架的企盼也是一直很高的。
Warp在我看来是这方面做的最好的,它有以下几个鲜明的特点:
一、充分利用JDK5的annotation,简化编程和配置文件
Warp基于Google Guice并且发扬光大,自身无配置文件,所有功能完成均通过annotation,所以编程相当简洁
二、大量使用JDK5的泛型编程,提供强类型安全保证
虽说脚本语言的Duck Typing理念很流行,不过Java的优势也就是类型安全,Spring大量运用反射和XML配置等于是放弃了Java的优势。Warp在泛型方面做的很好,我相信在IDE的帮助下,Warp编程会更轻松
三、Warp-persist提供了声明式的事务管理,终于可以取代Spring了
Google Guice很好很强大,但是它没有事务管理能力和资源管理能力,所以无法取代spring,但是Warp-persist填补了这一缺憾,注入和管理Hibernate很容易:
要声明事务比spring可简单多了:
Warp支持Hibernate/JPA的所有事务管理策略,不但注入方式简单,而且声明事务方式更简单,代码看着简洁,写着更省心。
四、Dynamic Finder实在很酷!
还是直接看代码吧:
用annotation声明一下,一行查询代码都没有,你还要DAO干啥呢?
带参数的绑定变量查询,还是一行代码不用写,DAO是啥?
带分页的查询,还是一行代码不用写,谁用DAO我跟谁急 !
五、Web层也极其简单
Warp-MVC模仿了Tapestry 5的架构,但是作者做了大量的改良和简化,作者解释了一下为什么不直接使用Tapestry,而是自己开发的理由。
Warp-MVC看起来像一个Tapestry的简化版,有组件的概念,事件响应的方式,但是非常易用,非常简洁,URL映射也通过annotation方式声明,作者在自己的博客上面提供了相关的简单示例,可以参考:
http://www.jroller.com/dhanji/
Warp框架是最近几年来,我看到的第一个走在正确发展方向上的Java Web框架:结构简单、易用使用、但充分发挥了Java自身的语法优势,非常值得期待!
目前Warp框架还不是特别成熟,但是Warp-persistent已经相当稳定了,如果你是使用Hibernate/Spring/Struts来开发项目的话,不妨试试Warp,把spring换掉改成Hibernate/Warp/Struts2.0,也是一个不错的解决方案,全部运用annotation,让你的项目Zero Configuration。
友情提醒:Warp官方网站无法直接访问,建议在FireFox浏览器上面安装gladder插件,跨越GFW。
Warp Framework - 官方网站
Warp框架充分利用了JDK5.0的Annotation和泛型机制,并且基于Google Guice这个IoC框架,提供了full-stack的Web开发设施,他主要包含了四个部分:
warp-persist框架:封装Hibernate和JPA,提供事务管理和持久化资源管理
warp-dynamic-finder:提供了基于Annotation的动态查询功能,让数据库查询变得异常简单,不再需要DAO层
warp-mvc:借鉴了Tapestry5,提供了一个基于事件机制和组件化的Web层,并且组件注入方式高度IoC化
warp-servlet: 提供了一些Servlet的封装和附加的高级功能,例如URL过滤,和其他web框架集成等等
这几年来,Java在Web开发框架方面的进步显得很有限,Spring/Hibernate组合对撼JBoss Seam形成两大竞争的主流态势,但是这两个Web框架在Web快速开发方面的创新还显得不够好:Spring是越来越臃肿了,配置文件也是越来越复杂难懂了;JBoss Seam门槛又过高,而且集成的JSF一向受人垢病,并非完美的解决方案,特别是在Ruby on Rails横空出世之后,Java社区对于简洁易用的快速web开发框架的企盼也是一直很高的。
Warp在我看来是这方面做的最好的,它有以下几个鲜明的特点:
一、充分利用JDK5的annotation,简化编程和配置文件
Warp基于Google Guice并且发扬光大,自身无配置文件,所有功能完成均通过annotation,所以编程相当简洁
二、大量使用JDK5的泛型编程,提供强类型安全保证
虽说脚本语言的Duck Typing理念很流行,不过Java的优势也就是类型安全,Spring大量运用反射和XML配置等于是放弃了Java的优势。Warp在泛型方面做的很好,我相信在IDE的帮助下,Warp编程会更轻松
三、Warp-persist提供了声明式的事务管理,终于可以取代Spring了
Google Guice很好很强大,但是它没有事务管理能力和资源管理能力,所以无法取代spring,但是Warp-persist填补了这一缺憾,注入和管理Hibernate很容易:
Injector injector = Guice.createInjector(..., PersistenceService .usingHibernate() .across(UnitOfWork.TRANSACTION) .buildModule());
要声明事务比spring可简单多了:
public class MyService {
@Inject Provider<Session> session;
@Transactional
public void createNewPerson() {
session.get().saveOrUpdate(new Person(...));
}
}
Warp支持Hibernate/JPA的所有事务管理策略,不但注入方式简单,而且声明事务方式更简单,代码看着简洁,写着更省心。
四、Dynamic Finder实在很酷!
还是直接看代码吧:
@Finder(query="from Person")
public List<Person> listAll() { return null; }
用annotation声明一下,一行查询代码都没有,你还要DAO干啥呢?
@Finder(query="from Person where firstName = :firstName")
Person find(@Named("firstName") String name);
带参数的绑定变量查询,还是一行代码不用写,DAO是啥?
@Finder(query="from Person") List<Person> listAll(@FirstResult int first, @MaxResults int max);
带分页的查询,还是一行代码不用写,谁用DAO我跟谁急 !
五、Web层也极其简单
Warp-MVC模仿了Tapestry 5的架构,但是作者做了大量的改良和简化,作者解释了一下为什么不直接使用Tapestry,而是自己开发的理由。
Warp-MVC看起来像一个Tapestry的简化版,有组件的概念,事件响应的方式,但是非常易用,非常简洁,URL映射也通过annotation方式声明,作者在自己的博客上面提供了相关的简单示例,可以参考:
http://www.jroller.com/dhanji/
Warp框架是最近几年来,我看到的第一个走在正确发展方向上的Java Web框架:结构简单、易用使用、但充分发挥了Java自身的语法优势,非常值得期待!
目前Warp框架还不是特别成熟,但是Warp-persistent已经相当稳定了,如果你是使用Hibernate/Spring/Struts来开发项目的话,不妨试试Warp,把spring换掉改成Hibernate/Warp/Struts2.0,也是一个不错的解决方案,全部运用annotation,让你的项目Zero Configuration。
友情提醒:Warp官方网站无法直接访问,建议在FireFox浏览器上面安装gladder插件,跨越GFW。
Warp Framework - 官方网站
评论
dhxyu
2008-04-27
不要下太大的结论吧?
取代是不可能的,存在就有理。
当然新的东西是可以尝试的,我们公司还使用oracle forms进行开发,当然是数据仓库和模型的架构决定的!
相信spring 3.0出来了,很多问题也会有相应的解决,期待更好的解决方案。
取代是不可能的,存在就有理。
当然新的东西是可以尝试的,我们公司还使用oracle forms进行开发,当然是数据仓库和模型的架构决定的!
相信spring 3.0出来了,很多问题也会有相应的解决,期待更好的解决方案。
hax
2008-04-18
ajoo 写道
robbin 写道
我不这么看。这个ViewBlog类似Webwork的Action,本身是prototype的,每次请求创建,为啥就不能有状态呢?就是RoR的controller也是一样,每次请求创建controller实例。
再说@Event,这个就是Webwork里面的Interceptor的东西,起到AOP作用的,在RoR里面也有类似的Filter概念,没觉得加一个@Event怎么会复杂。
不过话说回来,在ViewBlog这个具体的例子当中,使用@Event的方式来初始化数据,的确没有必要,例子举的不恰当。
状态不可怕,可怕的是状态变迁。这个例子里面,就涉及了before initialized和initialized两个状态。而且优先使用immutable也是基本的best practice吧?Guice也是强调constructor injection的。
interceptor不会有状态变化,所以无所谓。要说这个,更象servlet的init(),老掉牙很丑陋的东西。
ajoo同志深得我心,我批OperaMask的IoVC的那个例子的@BeforeRender也是同样的理由啊,可惜有人老是说我不懂JSF的6种phase云云。。。
indexchen
2008-03-24
Warp-persist提供了声明式的事务管理,终于可以取代Spring了
难道spring就没有声明式事务管理? 别动不动就取代,spring提供的远不止Ioc,DI,
spring 可以将第三方好的框架都集成到应用中,提高开发效率,这是很重要的。
难道spring就没有声明式事务管理? 别动不动就取代,spring提供的远不止Ioc,DI,
spring 可以将第三方好的框架都集成到应用中,提高开发效率,这是很重要的。
timerri
2008-03-24
一把新的瑞士军刀。你需要重新习惯它才能使用....
ivorytower
2008-03-24
对于SSH
更期待简洁
更期待简洁
ajoo
2008-03-23
光说不练假把式。我自己根据这个想法实现了一个基于Guice的rest框架。
嘿嘿,为什么没有@RestMethod之类的?因为我没想明白为什么rest method和资源定位不是正交的。拿到了Foo之后你怎么处理完全是自己的事情了,和框架可以毫无关系了。这样不是比框架大包大揽更好?
好处呢?简单,完全的依赖注入,除了这些rest参数,你可以注入任何Guice里面的依赖。
@Resource("foo/{foo.id}")
public class Foo {
@Inject public Foo(@RestParam("foo.id") String id) {
...
}
}
new ResourceBinder(binder()).bindResource(Foo.class);
bind(ResourceLocator.class).to(GuiceResourceLocator.class);
class FooAction {
private final ResourceLocator resourceLocator;
public String run() {
Foo foo = resourceLocator.getResource(request.getPathInfo(), Foo.class);
...
}
}
嘿嘿,为什么没有@RestMethod之类的?因为我没想明白为什么rest method和资源定位不是正交的。拿到了Foo之后你怎么处理完全是自己的事情了,和框架可以毫无关系了。这样不是比框架大包大揽更好?
好处呢?简单,完全的依赖注入,除了这些rest参数,你可以注入任何Guice里面的依赖。
zbird
2008-03-21
Norther 写道
wuyingsong 写道
manmoon 写道
零配置是没了,都转向硬编码了,我看不出annotation 比配置文件好到哪里。
首先要确认一点是什么是配置文件,哪些东西才是配置,像hibernate对象关系映射这种东西有人会在运行时修改吗?
没有的,这种东西就应该以更接近代码的形式出现,annotation的意义就在于此。
支持这个,老早就对JAVA的官僚反感了。
JAVA开发者老是会假定出很多在实际运行中根本不可能出现的变化。
struts在这方面实在是太明显了。
这么多的view配置了做少,难不成在产品发布后还有人去改jsp路径?
Norther
2008-03-19
wuyingsong 写道
manmoon 写道
零配置是没了,都转向硬编码了,我看不出annotation 比配置文件好到哪里。
首先要确认一点是什么是配置文件,哪些东西才是配置,像hibernate对象关系映射这种东西有人会在运行时修改吗?
没有的,这种东西就应该以更接近代码的形式出现,annotation的意义就在于此。
wuyingsong
2008-03-19
manmoon 写道
零配置是没了,都转向硬编码了,我看不出annotation 比配置文件好到哪里。
williamy
2008-03-14
秦始皇小时候家里穷,玩的东西很少,不过也算玩过积木,就说它吧
一个个积木是不同的,放在不同的口袋里,他想堆一个长城
但是长城好长,不容易一下就想清楚,于是我在地板上画了图,
图上表示了如何一个个积木组装起来。由于长城好长,从山海关到加疫关
于是地上的图也很长,后来秦始皇觉得自己一个人堆长城很有难度,于是就
自己搞定出一个方案,让农民工去建造
--------------------------------------------------
rod j以前玩C++的,玩Java很少,不过也算知道javaBean,就说他吧
一个个javabean是不同的,放在不同的package里,rod想写一个系统
系统很大,不容易一下想清楚,于是在xml上写了一些表述
xml上描述了如何一个个bean的组装过程,由于系统好大,从用户登录到用户积分
于是xml上的内容很长,后来rod觉得手工组装很难,于是就自己
搞定出一个方案,让程序去组装
所以说ioc本身出发点很简单的
一个个积木是不同的,放在不同的口袋里,他想堆一个长城
但是长城好长,不容易一下就想清楚,于是我在地板上画了图,
图上表示了如何一个个积木组装起来。由于长城好长,从山海关到加疫关
于是地上的图也很长,后来秦始皇觉得自己一个人堆长城很有难度,于是就
自己搞定出一个方案,让农民工去建造
--------------------------------------------------
rod j以前玩C++的,玩Java很少,不过也算知道javaBean,就说他吧
一个个javabean是不同的,放在不同的package里,rod想写一个系统
系统很大,不容易一下想清楚,于是在xml上写了一些表述
xml上描述了如何一个个bean的组装过程,由于系统好大,从用户登录到用户积分
于是xml上的内容很长,后来rod觉得手工组装很难,于是就自己
搞定出一个方案,让程序去组装
所以说ioc本身出发点很简单的
ajoo
2008-03-14
ozzzzzz 写道
我觉得ajoo现在有些跟自己较劲的意思。其实就这个事情来说,本无所谓对错,都有道理。关键是自己的权衡和选择。
而之所以我最近很少发表对java社区的看法,原因当然是我自己对java就不太通,水平不够。但是我还以为,java社区的框架看似不少,但是真正的说起来,又没多少。这些框架之间的哲学思路其实分析起来,仅仅是细节层面的不同,而无本质上的区别。而现在构架师满天飞,又看不出哪个出来设计一个自己的框架来。要说grails哲学稍微有所不同,但是又是外来户,不能算本土球员。
而本身java社区的框架层出不穷,就说明java这里需要框架这样的开发套路。而同时又可以说明,这些套路又都不是令人满意。因此我看,与其发明更多的套路,不如发明组织套路的法子出来,叫大家学会这个法子,自己整自己的套路出来来得彻底。
而之所以我最近很少发表对java社区的看法,原因当然是我自己对java就不太通,水平不够。但是我还以为,java社区的框架看似不少,但是真正的说起来,又没多少。这些框架之间的哲学思路其实分析起来,仅仅是细节层面的不同,而无本质上的区别。而现在构架师满天飞,又看不出哪个出来设计一个自己的框架来。要说grails哲学稍微有所不同,但是又是外来户,不能算本土球员。
而本身java社区的框架层出不穷,就说明java这里需要框架这样的开发套路。而同时又可以说明,这些套路又都不是令人满意。因此我看,与其发明更多的套路,不如发明组织套路的法子出来,叫大家学会这个法子,自己整自己的套路出来来得彻底。
死胖子是说springside这类的东西么?
quaff
2008-03-14
sorphi 写道
看来ajoo大哥很喜欢immutable,所以尤其喜欢Constructor injection
不过上面有些概念还是没有很多经验来体会差别,劳烦ajoo大哥您给讲讲?比如
* - Your class is not testable!
* + Only thing that works for some strange edge cases
* - Useless when Guice can't do instantiation itself, e.g. a servlet
你举的那个代码,每个请求都要对应一个action的构造函数,那怎么用url/actionmethod mapping?根据struts2.1的rest plugin,我臆想了一段伪码如下:
action pojo想要immutable,就得需要写mutable的Renderer和Binder之类的设施来存放中间状态。只不过是换了个地方而已。
引用
Guice best practices
Field vs. method vs. constructor injection
Field injection
* + Most compact syntax (good for a trivial custom provider, e.g.)
* - Can't take any special action upon injection
* - Your class is not testable!
Method injection
* + Isn't field injection
* + Only thing that works for some strange edge cases
Constructor injection
* + Fields can be final!
* + Injection cannot possibly have been skipped, even if Guice is not in the picture
* + Easy to see dependencies at a glance
* + It's what the idea of construction is all about
* - No optional injections
* - Useless when Guice can't do instantiation itself, e.g. a servlet
* - Subclasses need to "know about" the injections needed by their superclasses
* - Less convenient for tests that only "care about" one of the parameters
Field vs. method vs. constructor injection
Field injection
* + Most compact syntax (good for a trivial custom provider, e.g.)
* - Can't take any special action upon injection
* - Your class is not testable!
Method injection
* + Isn't field injection
* + Only thing that works for some strange edge cases
Constructor injection
* + Fields can be final!
* + Injection cannot possibly have been skipped, even if Guice is not in the picture
* + Easy to see dependencies at a glance
* + It's what the idea of construction is all about
* - No optional injections
* - Useless when Guice can't do instantiation itself, e.g. a servlet
* - Subclasses need to "know about" the injections needed by their superclasses
* - Less convenient for tests that only "care about" one of the parameters
不过上面有些概念还是没有很多经验来体会差别,劳烦ajoo大哥您给讲讲?比如
* - Your class is not testable!
* + Only thing that works for some strange edge cases
* - Useless when Guice can't do instantiation itself, e.g. a servlet
你举的那个代码,每个请求都要对应一个action的构造函数,那怎么用url/actionmethod mapping?根据struts2.1的rest plugin,我臆想了一段伪码如下:
public final class BlogsController {
private final Blogs blogs;
@Inject
public BlogsController(Blogs blogs){
this.blogs = blogs;
}
/** GET /blogs/?page={page} */
@Resource("/blogs/") @RestMethod("GET") @RestAccept("text/html")
public Renderer index(@RestParam("page") int page) {
return new Renderer("index.html")
.put("blogs", blogs.list(page));
}
/** GET /blogs/1 */
@Resource("/blogs/{id}") @RestMethod("GET") @RestAccept("text/json")
public Renderer show(@RestParam("id") String id) {
Blog blog = blogs.get(id);
return new Renderer("show.json")
.withEtag(...)
.lastModified(blog.getLastModified())
.put("blog", blog);
}
/** PUT /blogs/1 */
@Resource("/blogs/{id}") @RestMethod("PUT") @RestAccept("text/html")
public Renderer update(???) {
// how to do when we need to store some values from request into pojo but can't change pojo's
//state for protecting ajoo's faith? varargs in method scope?
//prepare , parameter/property binder, then save
return index(0);
}
...
}
public class Renderer {
private Map context;
public Render(String result);
@Inject public void setResponse(HttpResponse res);
@Inject public void setResponse(HttpRequest req);
public put(String key, Object value);
public void render();
...
}
action pojo想要immutable,就得需要写mutable的Renderer和Binder之类的设施来存放中间状态。只不过是换了个地方而已。
Guice推荐ctor injection,我来点评一下他说的优点
* + Fields can be final!
这个有什么实际意义?
* + Injection cannot possibly have been skipped, even if Guice is not in the picture
如果用方法注入,可以加一个比如@Required来强制必须注入
* + Easy to see dependencies at a glance
这个是鸡肋
* + It's what the idea of construction is all about
这个没明白说什么
再来加一个缺点,和getter/setter注入相比没办法在运行期改变,拿acegi举例
CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
\A/backend/switchuser\Z=ROLE_SUPERVISOR
\A/backend/switch\Z=ROLE_SUPERVISOR
\A/backend/exit\Z=ROLE_PREVIOUS_ADMINISTRATOR
\A/backend/.*\Z=ROLE_SUPERVISOR
这个是控制url访问权限的配置,在容器启动的时候就注入到bean里面了,也可以在webapp运行期间,修改它然后再set进去
quaff
2008-03-14
robbin 写道
melin 写道
rainlife 写道
使用struts2(CoC)+JPA+spring(注解),会是怎么样呢?
在java中这样的组合应该成经典,如果一味的最求zero 配置,也不是很完美,应该是注解和xml相结合,基本不会变动用注解,如果那些可变动的还是需要xml的,特别是spring2.5。提供的新特性(@Component,@Repository,@Service),大大简化了典型的三层结构的配置。
Spring在静态的配置文件当中描述bean的依赖关系(或者静态的Annotation),在某些情况下这是一个非常讨厌的限制,导致你很难在程序运行期修改或者创建bean的依赖关系。
比方说,你的程序根据某用户的操作,创建了quartz bean执行后台任务,这玩意你没办法事先在配置文件里面写死的,那你就麻烦大了,只能想办法自己写FactoryBean,在程序里面调用这个FactoryBean自己手工创建依赖。再例如你一个prototype的bean,在程序运行期创建的时候需要从程序里面传入一个构造器参数,这个参数可能来自你的业务逻辑,那你马上傻眼了,写FactoryBean吧,在程序里面自己create吧。类似这种情况还挺多的,Spring也就是管理Singleton的bean很好用,一旦涉及到prototype bean啥的,处处受限制。
所以这个IoC的玩意,你要在程序运行期玩花样,灵活起来,动态起来,Google Guice就比Spring好用不是一点半点。这就是为啥我推崇基于Google Guice的warp的原因,当然warp自己也有一些很不错的地方。
1.spring要更改bean的依赖关系可以手动的去get和set,也可以采用spring-dm,这是osgi的强项,不知道guice有什么更好的方法?
2.你说的quartz bean还是在自己的带面里面传入构造参数new出来比较好,然后获取spring里面org.quartz.Scheduler的实例,然后按照quartz的方式去处理,既然这个bean的构造参数是依赖业务逻辑不断的变,难道guice可以检测到然后得到不同的实例?
个人认为采用guice比采用spring好的只是代码上的优雅,对于设计并没有什么新意,因为IoC最近也没什么新概念,guice只是采用jdk5的annotation方式.
nazar
2008-03-14
花这么多时间讨论guice?没有看看tapestry-ioc吗?
吸收了很多guice的东东,而且可以独立的使用在应用程序中,而不是和tapestry web framework 绑定的。
吸收了很多guice的东东,而且可以独立的使用在应用程序中,而不是和tapestry web framework 绑定的。
icewubin
2008-03-14
ozzzzzz 写道
我觉得ajoo现在有些跟自己较劲的意思。其实就这个事情来说,本无所谓对错,都有道理。关键是自己的权衡和选择。
而之所以我最近很少发表对java社区的看法,原因当然是我自己对java就不太通,水平不够。但是我还以为,java社区的框架看似不少,但是真正的说起来,又没多少。这些框架之间的哲学思路其实分析起来,仅仅是细节层面的不同,而无本质上的区别。而现在构架师满天飞,又看不出哪个出来设计一个自己的框架来。要说grails哲学稍微有所不同,但是又是外来户,不能算本土球员。
而本身java社区的框架层出不穷,就说明java这里需要框架这样的开发套路。而同时又可以说明,这些套路又都不是令人满意。因此我看,与其发明更多的套路,不如发明组织套路的法子出来,叫大家学会这个法子,自己整自己的套路出来来得彻底。
而之所以我最近很少发表对java社区的看法,原因当然是我自己对java就不太通,水平不够。但是我还以为,java社区的框架看似不少,但是真正的说起来,又没多少。这些框架之间的哲学思路其实分析起来,仅仅是细节层面的不同,而无本质上的区别。而现在构架师满天飞,又看不出哪个出来设计一个自己的框架来。要说grails哲学稍微有所不同,但是又是外来户,不能算本土球员。
而本身java社区的框架层出不穷,就说明java这里需要框架这样的开发套路。而同时又可以说明,这些套路又都不是令人满意。因此我看,与其发明更多的套路,不如发明组织套路的法子出来,叫大家学会这个法子,自己整自己的套路出来来得彻底。
你这样说未免也太大了吧,从宣传上来讲,各个框架都有各自的宣传渠道或者是相当数量的布道者,每年都有相当数量的框架和自己号称是框架的东西出现,暂且认为都是框架吧,这些框架有些是特定条件下的产物,如早期的struts和webwok都是某些人基于在公司中的需要衍生出来的,有些是挂羊头卖狗肉如IBM在幕后操纵的,还有些一开始就为了商业目的启动的。还有些是为了解决特定领域的问题,你说的好像仅仅局限在web框架中啊。我认为即使是在web框架中,根据不同的系统特性,本来就有很多种业务特点和系统特点,有多种适合不同情况的框架的选择权本身就很好,难道一定要像微软那样大家都用一套,听起来不错,能减少重复劳动,实际呢,垄断带来死气沉沉和不思进取,从这个角度上来说新的框架出现对老框架地推动和鞭策也是很有效果的。
组织套路也算是个领域,也有类似框架和方法论的。“java这里需要框架这样的开发套路”不等于“我们需要把所有的框架集成起来”。
sorphi
2008-03-14
谢谢ajoo。资源定位器这个概念我理解了。不过我对REST的理解很肤浅,可能太局限于现有这些框架的路子。某个框架,或者某个想法出来了,首先用熟悉框架的经验去考察它。
ozzzzzz
2008-03-13
我觉得ajoo现在有些跟自己较劲的意思。其实就这个事情来说,本无所谓对错,都有道理。关键是自己的权衡和选择。
而之所以我最近很少发表对java社区的看法,原因当然是我自己对java就不太通,水平不够。但是我还以为,java社区的框架看似不少,但是真正的说起来,又没多少。这些框架之间的哲学思路其实分析起来,仅仅是细节层面的不同,而无本质上的区别。而现在构架师满天飞,又看不出哪个出来设计一个自己的框架来。要说grails哲学稍微有所不同,但是又是外来户,不能算本土球员。
而本身java社区的框架层出不穷,就说明java这里需要框架这样的开发套路。而同时又可以说明,这些套路又都不是令人满意。因此我看,与其发明更多的套路,不如发明组织套路的法子出来,叫大家学会这个法子,自己整自己的套路出来来得彻底。
而之所以我最近很少发表对java社区的看法,原因当然是我自己对java就不太通,水平不够。但是我还以为,java社区的框架看似不少,但是真正的说起来,又没多少。这些框架之间的哲学思路其实分析起来,仅仅是细节层面的不同,而无本质上的区别。而现在构架师满天飞,又看不出哪个出来设计一个自己的框架来。要说grails哲学稍微有所不同,但是又是外来户,不能算本土球员。
而本身java社区的框架层出不穷,就说明java这里需要框架这样的开发套路。而同时又可以说明,这些套路又都不是令人满意。因此我看,与其发明更多的套路,不如发明组织套路的法子出来,叫大家学会这个法子,自己整自己的套路出来来得彻底。
ajoo
2008-03-13
* - Your class is not testable!
field基本上都是private的。你没法在test case里面给它设一个mock值。Guice不象Spring,它老老实实告诉你,写单元测试不要靠容器,而是用JUnit/TestNG。
* + Only thing that works for some strange edge cases
不清楚。可能是说lifecycle的情况或者你需要做除了赋值以外的其它特殊动作。
* - Useless when Guice can't do instantiation itself, e.g. a servlet
servlet是由servlet容器直接调用无参构造函数创建的,Guice插不进去。
至于说这个rest的例子。我觉得warp和我的理想用法的共同点都是:直接的domain模型,一个对象代表一个资源。所以对rest method的响应不在这个pojo里面。分歧只在于我希望更直接的构造函数完成一切,而不是一些人为定义的特殊事件。
一个假想的用法是:
field基本上都是private的。你没法在test case里面给它设一个mock值。Guice不象Spring,它老老实实告诉你,写单元测试不要靠容器,而是用JUnit/TestNG。
* + Only thing that works for some strange edge cases
不清楚。可能是说lifecycle的情况或者你需要做除了赋值以外的其它特殊动作。
* - Useless when Guice can't do instantiation itself, e.g. a servlet
servlet是由servlet容器直接调用无参构造函数创建的,Guice插不进去。
至于说这个rest的例子。我觉得warp和我的理想用法的共同点都是:直接的domain模型,一个对象代表一个资源。所以对rest method的响应不在这个pojo里面。分歧只在于我希望更直接的构造函数完成一切,而不是一些人为定义的特殊事件。
一个假想的用法是:
interface ResourceLocator {
<T> T getResource(String path, Class<T> resourceType);
}
class FooServlet extends HttpServlet {
private ResourceLocator locator;
public void doGet(HttpServletRequest request, HttpServletResponse response) {
Foo foo = locator.getResource(request.getServletPath(), Foo.class);
// foo对象就是一个完全注射好的,对象当前请求的资源的实例。
response.getWriter().write(foo.getName());
}
}
sorphi
2008-03-13
看来ajoo大哥很喜欢immutable,所以尤其喜欢Constructor injection
不过上面有些概念还是没有很多经验来体会差别,劳烦ajoo大哥您给讲讲?比如
* - Your class is not testable!
* + Only thing that works for some strange edge cases
* - Useless when Guice can't do instantiation itself, e.g. a servlet
你举的那个代码,每个请求都要对应一个action的构造函数,那怎么用url/actionmethod mapping?根据struts2.1的rest plugin,我臆想了一段伪码如下:
action pojo想要immutable,就得需要写mutable的Renderer和Binder之类的设施来存放中间状态。只不过是换了个地方而已。
引用
Guice best practices
Field vs. method vs. constructor injection
Field injection
* + Most compact syntax (good for a trivial custom provider, e.g.)
* - Can't take any special action upon injection
* - Your class is not testable!
Method injection
* + Isn't field injection
* + Only thing that works for some strange edge cases
Constructor injection
* + Fields can be final!
* + Injection cannot possibly have been skipped, even if Guice is not in the picture
* + Easy to see dependencies at a glance
* + It's what the idea of construction is all about
* - No optional injections
* - Useless when Guice can't do instantiation itself, e.g. a servlet
* - Subclasses need to "know about" the injections needed by their superclasses
* - Less convenient for tests that only "care about" one of the parameters
Field vs. method vs. constructor injection
Field injection
* + Most compact syntax (good for a trivial custom provider, e.g.)
* - Can't take any special action upon injection
* - Your class is not testable!
Method injection
* + Isn't field injection
* + Only thing that works for some strange edge cases
Constructor injection
* + Fields can be final!
* + Injection cannot possibly have been skipped, even if Guice is not in the picture
* + Easy to see dependencies at a glance
* + It's what the idea of construction is all about
* - No optional injections
* - Useless when Guice can't do instantiation itself, e.g. a servlet
* - Subclasses need to "know about" the injections needed by their superclasses
* - Less convenient for tests that only "care about" one of the parameters
不过上面有些概念还是没有很多经验来体会差别,劳烦ajoo大哥您给讲讲?比如
* - Your class is not testable!
* + Only thing that works for some strange edge cases
* - Useless when Guice can't do instantiation itself, e.g. a servlet
你举的那个代码,每个请求都要对应一个action的构造函数,那怎么用url/actionmethod mapping?根据struts2.1的rest plugin,我臆想了一段伪码如下:
public final class BlogsController {
private final Blogs blogs;
@Inject
public BlogsController(Blogs blogs){
this.blogs = blogs;
}
/** GET /blogs/?page={page} */
@Resource("/blogs/") @RestMethod("GET") @RestAccept("text/html")
public Renderer index(@RestParam("page") int page) {
return new Renderer("index.html")
.put("blogs", blogs.list(page));
}
/** GET /blogs/1 */
@Resource("/blogs/{id}") @RestMethod("GET") @RestAccept("text/json")
public Renderer show(@RestParam("id") String id) {
Blog blog = blogs.get(id);
return new Renderer("show.json")
.withEtag(...)
.lastModified(blog.getLastModified())
.put("blog", blog);
}
/** PUT /blogs/1 */
@Resource("/blogs/{id}") @RestMethod("PUT") @RestAccept("text/html")
public Renderer update(???) {
// how to do when we need to store some values from request into pojo but can't change pojo's
//state for protecting ajoo's faith? varargs in method scope?
//prepare , parameter/property binder, then save
return index(0);
}
...
}
public class Renderer {
private Map context;
public Render(String result);
@Inject public void setResponse(HttpResponse res);
@Inject public void setResponse(HttpRequest req);
public put(String key, Object value);
public void render();
...
}
action pojo想要immutable,就得需要写mutable的Renderer和Binder之类的设施来存放中间状态。只不过是换了个地方而已。
ajoo
2008-03-13
robbin 写道
ajoo 写道
robbin 写道
我不这么看。这个ViewBlog类似Webwork的Action,本身是prototype的,每次请求创建,为啥就不能有状态呢?就是RoR的controller也是一样,每次请求创建controller实例。
再说@Event,这个就是Webwork里面的Interceptor的东西,起到AOP作用的,在RoR里面也有类似的Filter概念,没觉得加一个@Event怎么会复杂。
不过话说回来,在ViewBlog这个具体的例子当中,使用@Event的方式来初始化数据,的确没有必要,例子举的不恰当。
状态不可怕,可怕的是状态变迁。这个例子里面,就涉及了before initialized和initialized两个状态。而且优先使用immutable也是基本的best practice吧?Guice也是强调constructor injection的。
interceptor不会有状态变化,所以无所谓。要说这个,更象servlet的init(),老掉牙很丑陋的东西。
你说的固然有道理,但更像是一种编程味道的好恶,特别是这个例子的确举的不好。但它这样用,也不会导致代码出啥问题吧?
一个框架的评判很多时候是不能不去闻味道的。象这种给pojo强加一个特殊的中间状态并且不允许immutable的,我觉得不是很轻量,而且也和Guice的一贯精神不符。
发表评论
提醒: 该博客已发表在公共论坛,博客所有留言会成为论坛回贴,留言请注意遵守论坛发贴规则
- 浏览: 1678921 次
- 性别:

- 来自: 上海

- 详细资料
搜索本博客
我的相册
游乌镇
共 33 张
共 33 张
链接
最新评论
-
mod_rails尝鲜
我觉得还是mod_fcgid(不是mod_fastcgi)实际点
-- by zgd -
mod_rails尝鲜
hostingrails也已经提供mod_rails了
-- by leondu -
mod_rails尝鲜
dreamhost已经提供mod_rails了
-- by zgd -
关于JavaEye网站未来发展 ...
期待第三阶段目标的实现,但第三目标好像类似于google的云计算,建议赶紧开发, ...
-- by selectme_2008 -
总结一下大家对JavaEye网 ...
javaeye是我比较喜欢的一个网站,但盈利模式还是比较单一,让人怀疑网站是否能 ...
-- by selectme_2008






评论排行榜