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对象和扩展方法很巧妙的实现了配 ...
随机推荐
- 优雅的数组降维——Javascript中apply方法的妙用
将多维数组(尤其是二维数组)转化为一维数组是业务开发中的常用逻辑,除了使用朴素的循环转换以外,我们还可以利用Javascript的语言特性实现更为简洁优雅的转换.本文将从朴素的循环转换开始,逐一介绍三 ...
- iOS 线程间共享资源添加排它锁
#import "ViewController.h" @interface ViewController () @property(nonatomic,strong)NSThrea ...
- 【Junit 报错】No appenders could be found for logger (org.springframework.core.env.StandardEnvironment).
Junit报错 log4j:WARN No appenders could be found for logger (org.springframework.core.env.StandardEnvi ...
- MySQL - 问题集 - 触发器更新本表数据异常"Can’t update table ‘tbl’ in stored function/trigger because it is already used by statement which invoked this"
如果你在触发器里面对刚刚插入的数据进行了 insert/update, 则出现这个问题.因为会造成循环的调用. create trigger test before update on test fo ...
- 详解ASP.NET MVC的请求生命周期
本文的目的旨在详细描述asp.net mvc请求从开始到结束的每一个过程. 我希望能理解在浏览器输入url并敲击回车来请求一个asp.net mvc网站的页面之后发生的任何事情. 为什么需要关心这些? ...
- WIN32/API/SDK/MFC四者之间的联系和区别
上面大家都说Win32是一个子系统,这个当然是对的,不过我们有时候我们所说Win32通俗的就是指32位的Windows系统,从 windows95/98到NT/2000/XP都是32位Windows. ...
- Quick Apps for Sharepoint小型BI解决方案
Quick Apps for Sharepoint介绍 Quick Apps for Sharepoint前身是Quest Webpart ,由企业软件开发商QuestSoftware开发,Quest ...
- Media Formatters in ASP.NET Web API 2
原文:http://www.asp.net/web-api/overview/formats-and-model-binding/media-formatters 1. 网络媒体类型 媒体类型,也叫作 ...
- Python for Informatics 第11章 正则表达式四(译)
注:文章原文为Dr. Charles Severance 的 <Python for Informatics>.文中代码用3.4版改写,并在本机测试通过. 11.3 组合查询和抽取 如果我 ...
- 给MySQL增加mysql-udf-http和mysql-udf-json自定义函数,让MySQL有调用http接口和查询直接回JSON的能力
1.安装mysql-udf-httpyum install -y libcurl*下载地址:http://pan.baidu.com/s/1nuYZqR3tar zxvf mysql-udf-http ...