美文网首页
手写框架探险系列-control层的重新设计

手写框架探险系列-control层的重新设计

作者: 潇潇洒洒的写书 | 来源:发表于2019-05-06 14:07 被阅读0次

之前自己做的view

    /**通过uri获得对应处理的方法
     * 并不仅限于uri,这个就是一个对应Method的标识。
     * @param uri
     * @return
     */
    Method getHandler(String uri);

    /**供用户动态扩展
     * @param uri
     * @param handler
     */
    void addHandler(String uri, Method handler);

    /**处理请求。
     * @param request
     * @param response
     */
    void handleServlet(ServletRequest request, ServletResponse response);

整合spring mvc

  • 仅仅需要一个过滤器,把所有的Servlert都实例化,采用策略模式逐个执行。
  • 如果Method的映射有冲突的时候(一个业务只能对应一个Method),可以代理Response,当他有输出的时候(流,转发,重定向)往ThreadLocal设置一个标志。用来判断是否执行了。
  • 简单吧。整合Struts2也是一样的策略+代理。

改进

  • 可以看到上面的只对Servlet进行了处理。特别的单一。在现在的时候已经不仅仅是Servlet了,Websocket,RPC等等。这一系列的处理,我们这里的control层应该抽象于业务层之后,且统一所有的control。
  • 所有的协议不过就输入和输出。同时输入和输出可能在整体业务的任何地方调用。
  • 基于以上的考虑,也就需要一个上下文。把输入和输出抽象出来。
    Method getHandler(String uri);
    boolean addHandler(String uri, Method handler);
    <T> boolean handleServlet(TxnContext context,HandlerInterceptor<T>[] handlerInterceptors);

决定之后用自己的编译器和ClassLoad

  • 本来想利用jetty嵌入式实现热更新,把他整合到项目中,但是jetty的嵌入式开发不理想。可以扫描文件()但是就是不更新class,令人失望。
  • 同时,一个jetty需要自己整合一下,一个tomcat也需要,其它的都需要自己整合麻烦。不如基于框架的层面统一出一套热更新。
  • 对于开发来说,我们关闭ide的自动编译启动我们的项目,自己整合了一个Servlert服务器把编译的内容放入ide(提示)和服务器(运行用)中,同时每次访问都用控制层的ClassLoad加载。
  • 这里的嵌入式测试代码就是不往demo里面放了,在这里记录一下。
package com.google.code.garbagecan.jettystudy.sample6;

import org.eclipse.jetty.deploy.DeploymentManager;
import org.eclipse.jetty.deploy.PropertiesConfigurationManager;
import org.eclipse.jetty.deploy.bindings.DebugListenerBinding;
import org.eclipse.jetty.deploy.providers.WebAppProvider;
import org.eclipse.jetty.server.DebugListener;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.ContextHandlerCollection;
import org.eclipse.jetty.server.handler.HandlerCollection;
import org.eclipse.jetty.webapp.Configuration;
import org.eclipse.jetty.webapp.WebAppContext;
/*
- [Jetty官网-最下面](https://www.eclipse.org/jetty/documentation/current/embedding-jetty.html)
*/
public class CopyOfWebAppContextWithFolderServer {  
    public static void main(String[] args) throws Exception {    
        Server server = new Server(8080);  
        WebAppContext context = new WebAppContext();
        context.setContextPath("/myapp"); //org.apache.jasper.runtime.TldScanner
        String str = "C:/Users/Administrator/workspace/test/src/main/webapp/";
        // web.xml可以改成其他名字,如web1.xml。  
        // 如果不指明配置文件的位置,会根据项目资源setResourceBase路径找下面的web.xml。如果找不到,默认页面index.html优先于index.jsp
        context.setDescriptor(str + "WEB-INF/web.xml"); // maven项目web.xml路径
        context.setResourceBase(str);// maven项目资源路径
        // //普通项目web.xml路径
        //普通项目资源路径
        context.setParentLoaderPriority(true);
        
        HandlerCollection handlers = new HandlerCollection();
        ContextHandlerCollection contexts = new ContextHandlerCollection();
        handlers.setHandlers(new Handler[] { contexts, context });
        server.setHandler(handlers);
         
         DeploymentManager deployer = new DeploymentManager();
            DebugListener debug = new DebugListener(System.err,true,true,true);
            server.addBean(debug);
            deployer.addLifeCycleBinding(new DebugListenerBinding(debug));
            deployer.setContexts(contexts);
            deployer.setContextAttribute(
                    "org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern",
                    ".*/[^/]*servlet-api-[^/]*\\.jar$|.*/javax.servlet.jsp.jstl-.*\\.jar$|.*/[^/]*taglibs.*\\.jar$");

            WebAppProvider webapp_provider = new WebAppProvider();
            webapp_provider.setMonitoredDirName(str);
//          webapp_provider.setMonitoredDirName(jetty_base + "/webapps");
//          webapp_provider.setDefaultsDescriptor(jetty_home + "/etc/webdefault.xml");
            webapp_provider.setScanInterval(30);
            webapp_provider.setExtractWars(true);
            webapp_provider.setConfigurationManager(new PropertiesConfigurationManager());

            deployer.addAppProvider(webapp_provider);
            server.addBean(deployer);

            // === setup jetty plus ==
            Configuration.ClassList classlist = Configuration.ClassList
                    .setServerDefault( server );
            classlist.addAfter(
                    "org.eclipse.jetty.webapp.FragmentConfiguration",
                    "org.eclipse.jetty.plus.webapp.EnvConfiguration",
                    "org.eclipse.jetty.plus.webapp.PlusConfiguration");

            classlist.addBefore("org.eclipse.jetty.webapp.JettyWebXmlConfiguration",
                                "org.eclipse.jetty.annotations.AnnotationConfiguration");
        server.start();
        server.join();
    }
}

参考资料

相关文章

网友评论

      本文标题:手写框架探险系列-control层的重新设计

      本文链接:https://www.haomeiwen.com/subject/dnvfoqtx.html