play 源码分析

play 入口:java

play.server.Server类 bootstrap

主要作2件事情:服务器

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

2,new Server();  数据结构

这里play使用了netty做为底层通信服务器mvc

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

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

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

 

 play 是如何处理请求的?spa

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

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;
    }
}

 

三、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四、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

相关文章
相关标签/搜索