有論壇說,Java頂多是個語言,而稱不上平台(platform),真正的平台是Spring。而Spring現在觸角深入太多層面了,早把EJB幹掉成為J2EE的正宗了。會不會有一朝,Spring也像JBoss一樣,把Hibernate免費版本凍結到3.2.6.ga,之後都是商業版(金庸都可以改版賣錢,王語嫣陪慕容復做皇帝夢)。而還有誰能成替代Spring的IoC container的角色呢?除了Eclipse.org發行的Enquinox之外,就是Google出品的Guice了。Guice也真的只有DI的功用而已,不似Spring已經無所不能,而且備受撻伐的是,Guice全然委給annotation處理,這樣入侵程式碼太過嚴重,有違鬆耦合的原則。不過見仁見智,JDK 5.0推出annotation時也是飽受質疑。
不過Guice感覺上真的有比Spring好用些,除了我上篇初體驗之外,還學到以下幾種用法:
- 以下Module配接方式是相等的:
public class MyModule
extends AbstractModule
{
@Override
protected void configure() {
MyService myService = new MyServiceImpl();
bind(MyService.class).toInstance(myService);
}
}public class MyModuleImpl
implements Module
{
@Override
public void configure(Binder binder) {
binder.bind(MyService.class).to(MyServiceImpl.class);
}
} - 用到同一個instance的方式:上面左邊程式粉紅字片段。
- 設定Singleton方式:在class name上加個@Singleton就行。不過看來和Spring有個不同:Spring的Singleton是在context的唯一instance,而Guice的Singleton似乎是指JVM上…,或是該說同一個預設Class Loader上的唯一instance。
- 甚至為了單元測試,@ImplementedBy(MyServiceImpl.class)可以替代Guice.createInjector和@Inject使用,但interface適用class就被綁死了。
一個想闖出名堂的core framework,至少Servlet和JDBC要能相當支持。Guice可能不會在普遍的系統專案領域和Spring爭,而是在Google力推的Moible platform:Android和Cloud platform的GAE打開藍海疆界。以下參考http://www.imxylz.info/p/211.html來自己實作的飯粒,Guice預設MVC是Struts2,從Struts2的支援上看,顯示它也未必非Spring不可。這裡先用基礎的Servlet:
- web.xml設定:設定Filter及Listener,由Listener做Module配接初始化
<web-app>
<display-name>Archetype Created Web Application</display-name>
<filter>
<filter-name>GuiceFilter</filter-name>
<filter-class>com.google.inject.servlet.GuiceFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>GuiceFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<listener>
<listener-class>
com.foo.web.GuiceServletContextListener
</listener-class>
</listener>
</web-app> - Context Listener:用法和Java Main一樣,要單元測試應該更方便了。
public class GuiceServletContextListener extends
com.google.inject.servlet.GuiceServletContextListener {
@Override
protected Injector getInjector() {
return Guice.createInjector(new ServletModuleImpl());
}
} - Servlet Module:ServletModule是繼承AbstractModule,用serve(url-pattern).with(Servlet.class)替代bind(interface).to(implementation.class)配接。而Servlet的class可以設成@Singleton。
public class ServletModuleImpl extends ServletModule {
@Override
protected void configureServlets() {
serve("/echo").with(EchoServlet.class);
}
}
Guice也涉足到Scala語言,也可和AOP產品搭配。感覺比Spring for web.xml設定更單純。