自己动手写一个tomcat之5wrapper和container
写在前面源码 。本文引入负责维护servlet信息的container组件以及负责管理servlet生命周期的wrapper组件。1正文为了方便管理servlet的生命周期以及简化其他组件执行servlet的复杂度我们来引入wrapper组件对应如下类packagemonitomcat.server;// ...publicclassServletWrapper{privateServletinstancenull;privateStringservletClass;privateClassLoaderloader;privateStringname;protectedServletContainerparentnull;publicServletWrapper(StringservletClass,ServletContainerparent){this.parentparent;this.servletClassservletClass;try{loadServlet();}catch(ServletExceptione){e.printStackTrace();}}// ...publicServletloadServlet()throwsServletException{// ...}publicvoidinvoke(HttpServletRequestrequest,HttpServletResponseresponse)throwsIOException,ServletException{if(instance!null){instance.service(request,response);}}}接着定义负责管理servlet们的container组件当然这里是管理servlet的wrapper们了如下packagemonitomcat.server;// ...publicclassServletContainer{// ...publicvoidinvoke(HttpRequestrequest,HttpResponseresponse)throwsIOException,ServletException{ServletWrapperservletWrappernull;Stringurirequest.getUri();StringservletNameuri.substring(uri.lastIndexOf(/)1);StringservletClassNameservletName;servletWrapperservletInstanceMap.get(servletName);if(servletWrappernull){servletWrappernewServletWrapper(servletClassName,this);//servletWrapper.setParent(this);this.servletClsMap.put(servletName,servletClassName);this.servletInstanceMap.put(servletName,servletWrapper);}try{HttpServletRequestrequestFacadenewHttpRequestFacade(request);HttpServletResponseresponseFacadenewHttpResponseFacade(response);System.out.println(Call service());servletWrapper.invoke(requestFacade,responseFacade);}catch(Exceptione){System.out.println(e.toString());}catch(Throwablee){System.out.println(e.toString());}}}接着要调整负责调用servlet的servletprocessor类packagemonitomcat.server;importjavax.servlet.ServletException;importjava.io.IOException;publicclassServletProcessor{privateHttpConnectorconnector;publicServletProcessor(HttpConnectorconnector){this.connectorconnector;}publicvoidprocess(HttpRequestrequest,HttpResponseresponse)throwsIOException,ServletException{this.connector.getContainer().invoke(request,response);}}是不是简单多了代码也清新多了最后调整总指挥HttpServer类维护新增的container组件如下/** * 总的服务器对象负责管理类工作的对象类似于公司的管理层负责管理但不负责具体干活但管理本身不也是一种职责嘛所以也可以用单一职责来进行说明 */publicclassHttpServer{// public static final String WEB_ROOT System.getProperty(user.dir) File.separator webroot;publicstaticfinalStringWEB_ROOTSystem.getProperty(user.dir)File.separatortargetFile.separatorclassesFile.separatorwebroot;publicstaticfinalStringWEB_ROOT_SERVLETSystem.getProperty(user.dir)File.separatortargetFile.separatorclassesFile.separatormonitomcatFile.separatorserver;publicstaticvoidmain(String[]args){// 启动连接器试用连接器组件HttpConnectorconnectornewHttpConnector();connector.start();ServletContainerservletContainernewServletContainer();connector.setContainer(servletContainer);}}测试C:\Users\dell9020curl http://localhost:8080/servlet/monitomcat.server.TestServlet !DOCTYPE html html headmeta charsetutf-8titleTest/title/head body bgcolor#f0f0f0 h1 aligncentercongratulation, when you see me, indicate that your wrapper and container work well!!!/h12引入容器的概念首先做如下修改:ServletContext改为StandardContext ServletWrapper改为StandardWrapper Session改为StandardSession SessionFacade改为StandardSessionFacade HttpRequest改为HttpRequestImpl HttpResponse改为HttpResponseImpl HttpServer改为Bootstrap这里我们引入容器的概念使得各个组件更加方便管理。为了避免和当前的Container区分出来将当前的类ServletContainer修改为StandardContext。首相定义容器接口Containerpackagemonitomcat.server;// ...publicinterfaceContainer{publicstaticfinalStringADD_CHILD_EVENTaddChild;publicstaticfinalStringREMOVE_CHILD_EVENTremoveChild;publicStringgetInfo();publicClassLoadergetLoader();publicvoidsetLoader(ClassLoaderloader);publicStringgetName();publicvoidsetName(Stringname);publicContainergetParent();publicvoidsetParent(Containercontainer);publicvoidaddChild(Containerchild);publicContainerfindChild(Stringname);publicContainer[]findChildren();publicvoidinvoke(HttpServletRequestrequest,HttpServletResponseresponse)throwsIOException,ServletException;publicvoidremoveChild(Containerchild);}给出公共的基础实现publicabstractclassContainerBaseimplementsContainer{}让servlet的wrapper成为容器:publicclassStandardWrapperextendsContainerBaseimplementsWrapper{}让context成为容器publicclassStandardContextextendsContainerBaseimplementsContext{}3调整目录结构更接近tomcat调整目录为如下调整不影响功能。源码 。写在后面在进行软件设计的时候其实可以类比现实场景中的公司公司中有很多的职责不同的职责对应的就是不同的岗位当增加新职责时比如新增了晚上守夜的职责时就新增一个守夜人的岗位。软件设计也是这个道理同样有很多的职责而这里每个职责对应的就是一个类当增加新职责时就新增一个类。这样做的好处是职责清晰程序也更好维护扩展性更好。总之就是大家一起协作把活干好参考文章列表手把手带你写一个 MiniTomcat 。
