zoukankan      html  css  js  c++  java
  • play 源码分析

    play 入口:

    play.server.Server类 

    主要做2件事情:

    1,Play.init;    // 初始化,主要是配置的加载,插件的加载等等

    2,new Server();  

    这里play使用了netty作为底层通讯服务器

    //实例化ServerBootstrap 启动netty服务器(boss线程池、worker线程池)。
    ServerBootstrap bootstrap = new ServerBootstrap(new NioServerSocketChannelFactory( Executors.newCachedThreadPool(), Executors.newCachedThreadPool())

    boss线程池实际就是Acceptor线程池,负责处理客户端的TCP连接请求

    worker线程池是真正负责I/O读写操作的线程组

     play 是如何处理请求的?

    1、实例化ServerBootstrap 启动netty服务器(boss线程池、worker线程池),绑定IP、端口
    2、指定filter ,也就是PLAY中的HttpServerPipelineFactory,用于处理输入和输出报文

    public class HttpServerPipelineFactory implements ChannelPipelineFactory {
    
        public ChannelPipeline getPipeline() throws Exception {
    
            Integer max = Integer.valueOf(Play.configuration.getProperty("play.netty.maxContentLength", "-1"));
               
            ChannelPipeline pipeline = pipeline();
            PlayHandler playHandler = new PlayHandler();
            
            pipeline.addLast("decoder", new HttpRequestDecoder()); //处理httprequest 
            pipeline.addLast("aggregator", new StreamChunkAggregator(max));//实现http分块
            pipeline.addLast("encoder", new HttpResponseEncoder());//处理http返回
            pipeline.addLast("chunkedWriter", playHandler.chunkedWriteHandler);//http分块
    
            Integer gzip = Integer.valueOf(Play.configuration.getProperty("play.netty.gzip", "0"));
            if (gzip==1)
            {
                pipeline.addLast("compress", new HttpContentCompressor());//压缩
                pipeline.addLast("decompress", new HttpContentDecompressor());//解压
            }
            pipeline.addLast("handler", playHandler);//参数解析
            return pipeline;
        }
    }

    3、playHandler处理分析
    parseRequest:将nettyRequest解析为play.mvc.http.Request
    Play.pluginCollection.rawInvocation:执行PLAY插件列表
    CorePlugin:处理play内置的功能(状态):/@kill /@status
    DBPlugin:处理play内置功能(启动h2Server):/@db
    Evolutions:处理play内置功能(检查数据结构变更):/@evolutions/apply
    Invoker.invoke(new NettyInvocation(request, response, ... :开始执行代码
    放在线程池中去执行(play.pool)
    Invoker.java:Run some code in a Play! context
    Invocation:An Invocation in something to run in a Play! context
    init():detectChanges 检测代码变化,热部署,仅DEV模式(配置文件变化时重启)
    run():捕获异常,返回500
    before(); 执行所有插件beforeInvocation
    JPAPlugin事务开启
    execute();
    after(); 执行所有插件afterInvocation
    JPAPlugin事务关闭
    onSuccess();执行所有插件onInvocationSuccess
    TempFilePlugin临时文件删除
    execute():ActionInvoker.invoke 开始调用action
    4、ActionInvoker.invoke分析
    resolve:将request、response、params、Session放入线程变量;根据URL找到action类和方法
    解析请求内容,生成action参数
    handleBeforeValidations:执行action拦截器 @BeforeValidation @unless @only
    Play.pluginCollection.beforeActionInvocation: 执行play插件beforeActionInvocation
    PlayPlugin.beforeActionInvocation: 将错误信息加入Validation
    handleBefores:执行action拦截器 @before @unless @only
    invokeControllerMethod:执行controllers代码
    inferResult:处理controllers代码执行后的返回结果
    catch (InvocationTargetException ex) :捕获异常
    返回结果的异常(Result):保存cache
    其它异常:执行action拦截器 @Catch @unless @only
    handleAfters(request);:执行action拦截器 @after @unless @only
    catch (Result result)
    Play.pluginCollection.onActionInvocationResult(result); :
    ValidationPlugin.onActionInvocationResult:保存Validation.errors到cookies
    保存Session(cookies)
    result.apply(request, response);:根据result类型设置http code,http head,http body
    Play.pluginCollection.afterActionInvocation();:暂无实现
    handleFinallies:执行action拦截器 @Finally @unless @only

  • 相关阅读:

    高度优化
    c++函数学习-关于c++函数的林林总总
    重载操作符
    【一周一算法】算法7:Dijkstra最短路算法
    【一周一算法】算法6:只有五行的Floyd最短路算法
    【一周一算法】算法4:解密QQ号——队列
    【一周一算法】小哼买书
    【一周一算法】算法3:最常用的排序——快速排序
    【一周一算法】算法2:邻居好说话——冒泡排序
  • 原文地址:https://www.cnblogs.com/feiyunaima/p/6228202.html
Copyright © 2011-2022 走看看