|
该帖已经被评为精华帖
|
|
|---|---|
| 作者 | 正文 |
|
最后更新时间:2007-11-10
印象中,Spring就象上个世纪的产品。不论使用方便性和代码设计都相当20世纪。有了Guice,Spring似乎应该逐渐退隐,被遗忘于江湖了。我最近这个项目就是在从Spring往Guice移植。大家都很高兴终于不用在这个即将失事的火车上挤着了。一个哥们在白板上用红笔大字写上:“用xml写配制半点好处也木有!”。
然后就看到了Spring JavaConfig。和这个火药贴: http://www.jroller.com/habuma/entry/guice_vs_spring_javaconfig_a 本来都对Spring失去兴趣了,不过看这么多人为之正名,于是就去看了一下。总的来说呢,眼睛一亮,然后比较失望。 JavaConfig从语法上说比Guice 1.0又进了一步,使用了最简单直观的method,然后用一些annotation来增加功能。这个和Guice 2.0比较象。谁抄谁我不管,技术上就这么点东西,这年头,民工都快能造原子弹了。 简单的东西两者差不多。文章里比的是Guice 1.0, 但是我觉得拿快出来的Guice 2.0比较更加有意义一些。比如他那个KnightConfig的例子,用Guice 2.0写,大致是这样: public class KnightModule {
@Provide
public Knight knight() {
...
}
@Provide
public Quest quest() {
...
}
...
}
JavaConfig是这样: @Configuration
public class KnightConfig {
@Bean public Knight knight() {
KnightOfTheRoundTable knight = new KnightOfTheRoundTable("Bedivere");
knight.setQuest(quest());
return knight;
}
@Bean public Quest quest() {
return new HolyGrailQuest();
}
@Bean @SpringAdvice("execution(* *.embarkOnQuest(..))")
public MinstrelInterceptor minstelAdvice() {
return new MinstrelInterceptor();
}
}
除了annotation不同,都一样。JavaConfig基本上就是把xml的manual wiring换到Java里面了(一件非常积德的事情)。Walls喋喋不休地强调的Spring的非侵入性其实没半点意义。要是真不想用Guice的@Inject,你完全可以也写成这种manual wiring的形式(就象上面的例子一样),根本不会有侵入。Guice只不过是通过@Inject让你可以以少许的侵入换取编程的方便罢了。 我认为比较重要的,是两者如何解决“依赖”。这个骑士的例子不存在依赖,每个bean都不需要引用其它的bean。其实这种简单的例子根本就没有意义。你说你能看出来JavaConfig比直接用裸Java配制优势在哪?就在于你最后可以用: Knight knight = (Knight) ctxt.getBean("knight");
而不是简单的: Knight knight = new KnightModule().knight(); 显得比较sophisticated?今天我“春”了? 然后我就去找了JavaConfig的教程,看了一下它怎么解决依赖,下面是例子: @Bean(scope = DefaultScopes.SINGLETON)
public Person rod() {
return new Person("Rod Johnson");
}
@Bean(scope = DefaultScopes.PROTOTYPE)
public Book book() {
Book book = new Book("Expert One-on-One J2EE Design and Development");
book.setAuthor(rod()); // rod() method is actually a bean reference !
return book;
}
然后我就怅然太息。这就是Spring的想象力呀。还是xml那一套,不过是从: <property name="author" ref="rod"/> 变成了 book.setAuthor(rod()); 这到也罢了。但是看到人家自豪的宣称:“你以为rod()是个函数调用吗?哈,答错啦!扣10分。这其实是一个bean reference, 它不直接调用你简单的大脑自以为调用的rod()函数,也不要以为你在电脑前作弊,用F3/F4热键带你过去的就是正确的选项。正确的答案是这里通过Spring的魔法得到了一个singleton!强吧?”,我就吐了。 这里的魔术,不用说,又是用了cglib,给偷偷弄了一个子类给override了——虽然我看不见这个子类。 但是,用了cglib,也就意味着下面几个限制: 1. 必须有public default constructor。 2. 必须不能final 也就是说我这个Config类不能带状态,不能给它注射依赖。这些函数虽然不能是static(否则spring的魔法就失效了)但是作用跟static method一样。白马非马吗? 确实强悍啊。看来以后可以象oracle认证一样,弄个spring认证来骗钱好了。 算了,不够聪明的我还是看看Guice 2.0的吧:
@Provide @Singleton
public Person bob() {
return new Person("crazybob");
}
@Provide
public Book book(Person author) {
Book book = new Book("Guice!");
book.setAuthor(author);
return book;
}
恩。我发现我虽然比较笨,看这个代码似乎还没有什么困难。不过是两个一点花头没有的函数,我眼睛里看见的它做了什么,它就必然做了什么,所有经典物理定律完全适用,没有任何不符合常识的东西。而且这似乎更符合"don't call us, we'll call you"的精神。也不需要担心那么多限制。比如,我可以快乐地把book title当成参数注射到这个Module里面:
class BookModule {
private final String title;
BookModule(String title) {
this.title = title;
}
@Provide @Singleton
public Person bob() {
return new Person("crazybob");
}
@Provide
public Book book(Person author) {
Book book = new Book(title);
book.setAuthor(author);
return book;
}
}
想怎么搞就怎么搞,因为BookModule自己也不过就是一个没什么限制的Pojo。 声明:JavaEye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
|
|
| 返回顶楼 | |
|
最后更新时间:2007-11-10
坚持xml,为了config让java类贴很多的膏药代码,道德败坏阿
|
|
| 返回顶楼 | |
|
最后更新时间:2007-11-10
比较笨,没看懂最后那段代码(把book title当成参数注射到这个Module里面)有什么比用Spring要快乐一些?ajoo能否再解说一下?
|
|
| 返回顶楼 | |
|
最后更新时间:2007-11-10
movingboy 写道 比较笨,没看懂最后那段代码(把book title当成参数注射到这个Module里面)有什么比用Spring要快乐一些?ajoo能否再解说一下?
Guice 2.0还没出来。一切只是我的乐观预测(因为,如果需要,我自己也可以在Guice 1.0外围写这么一个分析annotation来自动生成Module的东西)。 比如: String title = ...; Module module = Modules.createProviderModule(new BookModule(title)); Injector injector = Guice.createInjector(module); Book book = injector.getInstance(Book.class); 用JavaConfig,可能只能如此:
ApplicationContext ctxt = new JavaConfigContext(BookConfig.class);
// 没办法往BookConfig.class里面注射。
Book book = (Book) ctxt.getBean("book");
|
|
| 返回顶楼 | |
|
最后更新时间:2007-11-12
the comparison doesn't make any sense
|
|
| 返回顶楼 | |
|
最后更新时间:2007-11-13
用annotation写配置又比xml好在哪里?我也没看出来,总的来说,我感觉全局的配置用xml来做比较好,一些细粒度的针对单个类或者方法的配置用annotation比较好,所以比较理想的状况是两者结合起来使用,完全没有必要把它们对立起来。
|
|
| 返回顶楼 | |
|
最后更新时间:2007-11-11
感觉用xml也是优于annotation。 比较同意 cppasm 说的。 像那些Service Dao定义的话, 觉得定义在一个xml中更直观。
|
|
| 返回顶楼 | |
|
最后更新时间:2007-11-11
我就象在街道网贴Hibernate vs. Toplink 一样的无助啊。走错门儿了。
|
|
| 返回顶楼 | |
|
最后更新时间:2007-12-17
为什么xml就不好呢? 同问
|
|
| 返回顶楼 | |
|
最后更新时间:2007-11-12
思维的习惯问题?我倒是觉得XML可以以一种更友好的图形化的方式展现,并且是可以运行期动态调整的。
|
|
| 返回顶楼 | |















