博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
play 源码分析
阅读量:4661 次
发布时间:2019-06-09

本文共 3278 字,大约阅读时间需要 10 分钟。

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

转载于:https://www.cnblogs.com/feiyunaima/p/6228202.html

你可能感兴趣的文章
CodeForces 708B Recover the String
查看>>
CodeForces 666A Reberland Linguistics(DP)
查看>>
【题解】洛谷P2421[NOI2002]荒岛野人 (Exgcd)
查看>>
EXT学习笔记——几个小问题
查看>>
《算法图解》——第二章 选择排序
查看>>
多Region下HBase写入问题
查看>>
VueJs2.0建议学习路线
查看>>
temporary
查看>>
idea创建maven-archetype-webapp项目无java目录
查看>>
WebSocket入门及示例
查看>>
第四周-第08章节-Python3.5-装饰器
查看>>
单点登录跳转失败(原因是 主票据申请子票据失败) asp.net 同站点下不同应用间不同版本Framework问题...
查看>>
1、搭建Struts2开发环境
查看>>
DAY1--Python基础1
查看>>
Use "OR" in SQL with caution
查看>>
[super class] 和 [self superclass] 区别
查看>>
Visual Studio 2012 無法開啟 ASP.NET MVC2 專案的解決流程筆記
查看>>
mapreduce中map和reduce个数
查看>>
3 [面向对象]-组合,抽象类,接口
查看>>
2-[HTML]--介绍
查看>>