WebContextBuilder是产品的制造机器,他的实现类可以自定义,不同的实现类,对应不同的产品制造方式。
WebContext 是产品
WebContextFactory对WebContextBuilder进行了封装,让购买者和产品的生产进行解耦
public class WebContextFactory { public static WebContext get() { if (builder == null) { log.warn("Missing WebContextBuilder. Is DWR setup properly?"); return null; } return builder.get(); } private static WebContextBuilder builder = null; //此方法在容器启动时调用,所以WebContextBuilder的实现类可以自己定义,在启动时注入 public static void attach(Container container) { WebContextFactory.builder = container.getBean(WebContextBuilder.class); } public interface WebContextBuilder { WebContext get(); void engageThread(Container container,HttpServletRequest request,HttpServletResponse response); void disengageThread(); } /** * The log stream */ private static final Log log = LogFactory.getLog(WebContextFactory.class); }
DwrServlet 类webContextBuilder 的使用
doPost方法里使用构建器webContextBuilder负责本线程webContext对象的生产和销毁
在后面Handler方法里使用工厂WebContextFactory生产产品
public void init(ServletConfig servletConfig) throws ServletException { super.init(servletConfig); try { StartupUtil.logStartup(getClass().getSimpleName(),servletConfig); container = createContainer(servletConfig); //DwrServlet启动的时候赋予webContextBuilder的实现类对象 webContextBuilder = container.getBean(WebContextBuilder.class); configureContainer(container,servletConfig); } catch (ServletException ex) { throw ex; } catch (Exception ex) { log.fatal("init Failed",ex); throw new ServletException(ex); } finally { if (webContextBuilder != null) { webContextBuilder.disengageThread(); } } } @Override public void doPost(HttpServletRequest request,HttpServletResponse response) throws IOException,ServletException { try { //由webContextBuilder生产一个webContext对象, //此webContext对象在此线程的后面整个请求处理的过程中都能通过WebContextFactory.get()访问到 //webContextBuilder内部使用ThreadLocal来保存webContext对象,所以只用本线程能访问 webContextBuilder.engageThread(container,request,response); UrlProcessor processor = container.getBean(UrlProcessor.class); processor.handle(request,response); } finally { //由webContextBuilder回收一个webContext产品 webContextBuilder.disengageThread(); } }