Guice Webapp Insight

guice web dataflow:

Basic Design Concept:

  1) HttpRequest/HttpResponse will always be created by WebContainer(jetty/tomcat) and Guice will reuse/wrap them.

  2) For Servlet that match the url pattern in ServletModule, they will be created by Guice instead, their service() will called by guice filtering.

  3) For Servlet that doesn't match the url pattern defined in ServletModule, they will be created by WebContainer directly.

 

1) Listener:

<listener>
	<listener-class>edu.xmu.webapp.core.MyListener</listener-class>
</listener>
public class MyListener extends GuiceServletContextListener {
	@Override
	protected Injector getInjector() {
		return Guice.createInjector(new MyServletModule());
	}
}
public class MyServletModule extends ServletModule {
	@Override
	protected void configureServlets() {
		serve("*.html").with(MyServlet.class);
	}
}

2) Listener startup:

public abstract class GuiceServletContextListener
    implements ServletContextListener {
  public void contextInitialized(ServletContextEvent servletContextEvent) {
    final ServletContext servletContext = servletContextEvent.getServletContext();

    GuiceFilter.servletContext = new WeakReference<ServletContext>(servletContext);

    Injector injector = getInjector(); // will invoke our own getInjector() in listener; MyServletModule.configureServlets() will be invoked
    injector.getInstance(InternalServletModule.BackwardsCompatibleServletContextProvider.class)
        .set(servletContext);
    servletContext.setAttribute(INJECTOR_NAME, injector);
  }
}
// MyListener
@Override
protected Injector getInjector() {
	return Guice.createInjector(new MyServletModule());
}
// Guice
public static Injector createInjector(Stage stage,
   Iterable<? extends Module> modules) {
   return new InternalInjectorCreator()
     .stage(stage)
     .addModules(modules)
     .build();
}
// Elements
public static List<Element> getElements(Stage stage, Iterable<? extends Module> modules) {
  RecordingBinder binder = new RecordingBinder(stage);
  for (Module module : modules) {
    binder.install(module); // here our own module(MyServletModule) will be installed
  }
  return Collections.unmodifiableList(binder.elements);
}
// MyServletModule
@Override
protected void configureServlets() {
	serve("*.html").with(MyServlet.class);
}

3) 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>

4) Serve Request with guice created servlet:

    Request URL:

http://localhost:8080/webapp-core/aaa.html
// GuiceFilter
public void doFilter(ServletRequest servletRequest,
    ServletResponse servletResponse, FilterChain filterChain) {
 filterPipeline.dispatch(servletRequest, servletResponse, filterChain);
}
// ManagedFilterPipeline
public void dispatch(ServletRequest request, ServletResponse response,
    FilterChain proceedingFilterChain) {
  new FilterChainInvocation(filterDefinitions, servletPipeline, proceedingFilterChain)
        .doFilter(withDispatcher(request, servletPipeline), response);
}
// FilterChainInvocation
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse){
  servletPipeline.service(servletRequest, servletResponse);
}
// ServletPipeline
public boolean service(ServletRequest request, ServletResponse response) {
  //stop at the first matching servlet and service
  for (ServletDefinition servletDefinition : servletDefinitions) {
    if (servletDefinition.service(request, response)) { // Here our own servlet is invoked
      return true;
    }
  }
  //there was no match...
  return false;
}

5) Serve Request with web container created servlet:

http://localhost:8080/webapp-core/formalServlet
<servlet>
	<servlet-name>formalServlet</servlet-name>
	<servlet-class>edu.xmu.webapp.servlet.FormalServlet</servlet-class>
</servlet>
<servlet-mapping>
	<servlet-name>formalServlet</servlet-name>
	<url-pattern>/formalServlet</url-pattern>
</servlet-mapping>
// GuiceFilter
public void doFilter(ServletRequest servletRequest,
    ServletResponse servletResponse, FilterChain filterChain) {
  filterPipeline.dispatch(servletRequest, servletResponse, filterChain);
}
// ManagedFilterPipeline
public void dispatch(ServletRequest request, ServletResponse response,
    FilterChain proceedingFilterChain) {
  new FilterChainInvocation(filterDefinitions, servletPipeline, proceedingFilterChain)
      .doFilter(withDispatcher(request, servletPipeline), response);
}
// FilterChainInvocation
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse)
      throws IOException, ServletException {
  index++;

  // Our url doesn't match any of defined guice serve url, thus serviced is false
  final boolean serviced = servletPipeline.service(servletRequest, servletResponse);

  //dispatch to the normal filter chain only if one of our servlets did not match
  if (!serviced) {
    proceedingChain.doFilter(servletRequest, servletResponse);
  }
}
// proceedingChain is an instance of "FilterChain", it will invoke all the following filters configed in web.xml, and then invoke correspond service() in target Servlet.
// From here, guice has transferred the filter/servlet control to web container(tomcat/jetty).

 

Reference Links:

1) http://insidecoding.com/2013/02/05/using-google-guice-in-web-applications/

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值