部分(1):GUICE 与 Servlet 集成
http://code.google.com/p/google-guice/wiki/Servlets
Guice 提供了与 Servlet 的集成,可以完全替代 web.xml,使用类型安全,Java程序员所习惯的方式对 servlet 和 filter 进行配置。
<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>
首先,下载最新版本的 guice-servlet jar 包,将其与 guice 的包共同放在 classpath 路径下。然后将 GuiceFilter 放在 web.xml 的起始位置,这样,对于任何路径,guiceFilter 都会被使用,得到控制。
下面,要对 Guice 进行配置,方法是: Guice.createInjector(newServletModule());
这句话可以在任何时候被调用,但推荐的做法是在一个 ServletContextListener 中被调用,这个 Listener 在 Web 应用启动时被调用,在任何请求到来之前。做法如下,首先扩展 Google 提供的基类:
public class MyGuiceServletConfig extends GuiceServletContextListener {
@Override
protected Injector getInjector() {
return Guice.createInjector(new ServletModule());
}
}
然后在 web.xml 中进行注册
<listener>
<listener-class>com.example.MyGuiceServletConfig</listener-class>
</listener>
配置 servlet 是在 ServletModule 中进行的。以下是一个匿名类的例子:
Guice.createInjector(, new ServletModule() {
@Override
protected void configureServlets() {
serve("*.html").with(MyServlet.class)
}
}
可以用 web.xml风格的路径限制法 serve("/my/*").with(MyServlet.class)。
也可以类似地配置 filter:
filter("/*").through(MyFilter.class);
注意:每个 servlet 和 filter 都必须是 @Singleton,必须在标注或者 module 里面指明,所有不是 Singleton 的 scope 都是错误。这与 Servlet 的规范一致。
安装了 ServletModule 模块后,任何 Guice 注入的实例都可以被注入下面的对象:
@RequestScoped
class SomeNonServletPojo {
@Inject
public SomeNonServletPojo(HttpServletRequest request, HttpServletResponse response, HttpSession session) {
}
}
此外,http请求的参数可以如此注入: @Inject @RequestParameters Map<String, String[]> params;
分配顺序:
filter 和 servlet 将会按照在 ServletModule 里面出现的顺序分配。
此外,可以一次匹配多个路径: serve("*.html", "/my/*").with(MyServlet.class);
正则文法匹配:serveRegex("(.)*ajax(.)*").with(MyAjaxServlet.class)
指定初始化参数:
Map<String, String> params = new HashMap<String, String>();
params.put("coffee", "Espresso");
params.put("site", "google.com");
serve("/*").with(MyServlet.class, params)
这些参数可以用
getInitParams 得到。
其他高级特性省略不再讨论。
部分(2):GUICE 与 Vaadin 集成
http://vaadin.com/wiki/-/wiki/Main/Integrating Vaadin with Guice 2.0
首先,下载 guice-2.0.jar, guice-servlet-2.0.jar, aopalliance.jar,将这些包拷贝到
WebContent/WEB-INF/lib/ 目录。
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.Singleton;
import com.vaadin.Application;
import com.vaadin.terminal.gwt.server.AbstractApplicationServlet;
@Singleton
public class GuiceApplicationServlet extends AbstractApplicationServlet {
protected final Provider<Application> applicationProvider;
@Inject
public GuiceApplicationServlet(Provider<Application> applicationProvider) {
this.applicationProvider = applicationProvider;
}
@Override
protected Class getApplicationClass() throws ClassNotFoundException {
return Application.class;
}
@Override
protected Application getNewApplication(HttpServletRequest request) throws ServletException {
return applicationProvider.get();
}
}
上面这个class 可以直接拷贝到项目中不需要改变。Provider 由 Guice 注入,为每个用户创建一个 Application 实例。
下面是一个简单的 Application 的例子。其中参数 text 是被注入的。
#!java
import com.google.inject.Inject;
import com.google.inject.name.Named;
import com.vaadin.Application;
import com.vaadin.ui.Label;
import com.vaadin.ui.Window;
public class MyApplication extends Application {
@Inject @Named("welcome") protected String text;
@Override
public void init() {
Window window = new Window();
window.addComponent(new Label(text));
setMainWindow(window);
}
}
初始化,需要写一个 Guice 的 GuiceServletContextListener来配置 ServletModule,配置 Servlet,Application,以及其他 Guice 管理的实例,比如上面例子用到的 text。
#!java
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.name.Names;
import com.google.inject.servlet.GuiceServletContextListener;
import com.google.inject.servlet.ServletModule;
import com.google.inject.servlet.ServletScopes;
import com.vaadin.Application;
public class MyServletConfig extends GuiceServletContextListener {
@Override
protected Injector getInjector() {
ServletModule module = new ServletModule() {
@Override
protected void configureServlets() {
serve("/*").with(GuiceApplicationServlet.class);
bind(Application.class).to(MyApplication.class).in(ServletScopes.SESSION);
bindConstant().annotatedWith(Names.named("welcome")).to("This is my first Vaadin/Guice Application");
}
};
Injector injector = Guice.createInjector(module);
return injector;
}
}
web.xml 需要如此配置,来启动 Guice Filter 和上面的那个配置模块 (Listener)
<web-app>
<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>de.timedout.vaadin.guice.MyServletConfig</listener-class>
</listener>
</web-app>