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对象和扩展方法很巧妙的实现了配 ...
随机推荐
- AutoMapper搬运工之自定义类型转换
前言 最近还挺忙,还有点累,一直都没更新了,实在是懒呀.正题之前先说点别的,最近公司要扩张了,需要大量开发,领导说推荐有钱可以拿,如此好机会,我就趁机做个广告.ShippingRen.com招募.NE ...
- Reversing Bits in C
英文原文: http://corner.squareup.com/2013/07/reversing-bits-on-arm.html 本文讲解翻转bit位的一些方法,例如如何将1001 1101变为 ...
- linux 下如何 makefile
本文目的: 尝试着把makefile讲解清楚.非原创,仅仅是学习笔记和备忘录之用. makefile 的目的和好处: 一个工程中的源文件不计数,其按类型.功能.模块分别放在若干个目录中,makefil ...
- POJ 2559 Largest Rectangle in a Histogram ——笛卡尔树
[题目分析] 本来是单调栈的题目,用笛卡尔树可以快速的水过去. 把每一个矩阵看成一个二元组(出现的顺序,高度). 然后建造笛卡尔树. 神奇的发现,每一个节点的高度*该子树的大小,就是这一块最大的子矩阵 ...
- SOAPUI使用教程-MockServices工作原理
在soapUI的可让您只需从WSDL基础服务创建一个基于WSDL服务的符合标准的模拟.被称为“MockService”,这可以直接从内部的soapUI运行,命令行浇道,或甚至标准servlet容器. ...
- 踩坑事件:不能对基于文本的临时表使用sql insert语句
先来描述一下问题: 如果你是从基于文本的数据源来创建DataFrame的,当你将DataFrame注册为临时表后,如果对这个临时表进行insert into 操作,会抛出异常的. 问题答案参见:htt ...
- Hello Java
用记事本或者Eclipse编写如下代码 public class JavaAPP{ public static void main(String[] args){ System ...
- YUM源设置
1挂载光盘 先创建一个文件 /aaa 然后挂载mount /dev/cdrom /aaa 进入 /aaa ls 查看是否挂载OK 2进入yum文件夹.将除Media以外的所有文件名改为XXXXXX ...
- JavaScript必须了解的知识点总结【转】
整理的知识点不全面但是很实用. 主要分三块: (1)JS代码预解析原理(包括三个段落): (2)函数相关(包括 函数传参,带参数函数的调用方式,闭包): (3)面向对象(包括 对象创建.原型链,数据类 ...
- awk匹配
输出匹配funcno或type:awk 'funcno|type' 输出两次正则表达式匹配之间的行:awk '/funcno/, /type/' 删除所有的空行:awk NF 从第8行输出到第12行: ...