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
play 源码分析的更多相关文章
- ABP源码分析一:整体项目结构及目录
ABP是一套非常优秀的web应用程序架构,适合用来搭建集中式架构的web应用程序. 整个Abp的Infrastructure是以Abp这个package为核心模块(core)+15个模块(module ...
- HashMap与TreeMap源码分析
1. 引言 在红黑树--算法导论(15)中学习了红黑树的原理.本来打算自己来试着实现一下,然而在看了JDK(1.8.0)TreeMap的源码后恍然发现原来它就是利用红黑树实现的(很惭愧学了Ja ...
- nginx源码分析之网络初始化
nginx作为一个高性能的HTTP服务器,网络的处理是其核心,了解网络的初始化有助于加深对nginx网络处理的了解,本文主要通过nginx的源代码来分析其网络初始化. 从配置文件中读取初始化信息 与网 ...
- zookeeper源码分析之五服务端(集群leader)处理请求流程
leader的实现类为LeaderZooKeeperServer,它间接继承自标准ZookeeperServer.它规定了请求到达leader时需要经历的路径: PrepRequestProcesso ...
- zookeeper源码分析之四服务端(单机)处理请求流程
上文: zookeeper源码分析之一服务端启动过程 中,我们介绍了zookeeper服务器的启动过程,其中单机是ZookeeperServer启动,集群使用QuorumPeer启动,那么这次我们分析 ...
- zookeeper源码分析之三客户端发送请求流程
znode 可以被监控,包括这个目录节点中存储的数据的修改,子节点目录的变化等,一旦变化可以通知设置监控的客户端,这个功能是zookeeper对于应用最重要的特性,通过这个特性可以实现的功能包括配置的 ...
- java使用websocket,并且获取HttpSession,源码分析
转载请在页首注明作者与出处 http://www.cnblogs.com/zhuxiaojie/p/6238826.html 一:本文使用范围 此文不仅仅局限于spring boot,普通的sprin ...
- ABP源码分析二:ABP中配置的注册和初始化
一般来说,ASP.NET Web应用程序的第一个执行的方法是Global.asax下定义的Start方法.执行这个方法前HttpApplication 实例必须存在,也就是说其构造函数的执行必然是完成 ...
- ABP源码分析三:ABP Module
Abp是一种基于模块化设计的思想构建的.开发人员可以将自定义的功能以模块(module)的形式集成到ABP中.具体的功能都可以设计成一个单独的Module.Abp底层框架提供便捷的方法集成每个Modu ...
- ABP源码分析四:Configuration
核心模块的配置 Configuration是ABP中设计比较巧妙的地方.其通过AbpStartupConfiguration,Castle的依赖注入,Dictionary对象和扩展方法很巧妙的实现了配 ...
随机推荐
- Intellij IDEA中的Mybatis Plugin破解
具体的破解过程请看:https://github.com/luyanliang/profile/blob/master/idea/plugin/MybatisPlugin/Mybatis-Plugin ...
- Python lambda函数
python允许定义单行的小函数,定义lambda函数的形式如下: lambda 参数:表达式lambda函数默认返回表达式的值,可接收任意个参数,包括可选参数,但是表达式只有一个.
- 常见的几个Python面试题
str = "abcdaab" #字符串反转 print str[::-1] #统计str字符串中出现'a'的次数 print str.count('a') #pyhon可以用+作 ...
- docker1.4版本devicemapper修改容器硬盘大小
升级docker最新版(1.4.0)后,发现容器的硬盘空间只有10G,如果需要指定初始硬盘大小,目前的做法还比较粗暴,更改docker daemon的启动命令,然后删掉目前机器的已有镜像,重启dock ...
- CS: Marshalling and Unmarshalling, Serialization and Unserialization
Link1: https://en.wikipedia.org/wiki/Marshalling_(computer_science) Quote: " Comparison with se ...
- 【Ajax 基础学习】
http://www.cnblogs.com/guduoduo/p/3681296.html 今天简单的学习了 Ajax 的基础知识,总结在这里.部分代码不是原创,特此说明. [Ajax 简介] AJ ...
- [USACO] 铺放矩形块 题解
题目大意: 给定4个矩形块,找出一个最小的封闭矩形将这4个矩形块放入,但不得相互重叠.所谓最小矩形指该矩形面积最小. 思路: 枚举矩形的安放顺序,再按照题目所给的图判断即可,主要要想到枚举. 代码: ...
- 概率DP
POJ 3744 Scout YYF I 这就是一个乱搞题,暴力发现TLE了,然后看了看discuss里说可以矩阵加速,想了一会才想明白怎么用矩阵,分着算的啊.先算f[num[i]-1]之类的,代码太 ...
- 利用轮播原理结合hammer.js实现简洁的滑屏功能
最近有个任务,做一个非常小的h5的应用,只有2屏,需要做横向的全屏滑动切换和一些简单的动画效果,之前做这种东西用的是fullpage.js和jquery,性能不是很好,于是就想自己动手弄一个简单的东西 ...
- google jquery用不了啦,你准备好了吗
今天,相信很多网站开发人员都有这感觉,明明正常的页面却无法工作了,莫名其妙的错误,笔者也遇到这种错误,细查之下才发现google jquery用不了啦,通过firefox调试发现找不到jquery了, ...