swoft运行流程
启动命令 php bin/swoft http:start
或者 swoftctl run -c http:start
1 入口文件 bin/swoft.php
#!/usr/bin/env php
<?php // Bootstrap
require_once __DIR__ . '/bootstrap.php'; Swoole\Coroutine::set([
'max_coroutine' => 300000,
]); // Run application
(new \App\Application())->run();
new Application 进入文件 app/Application
<?php declare(strict_types=1);
/**
* This file is part of Swoft.
*
* @link https://swoft.org
* @document https://swoft.org/docs
* @contact group@swoft.org
* @license https://github.com/swoft-cloud/swoft/blob/master/LICENSE
*/ namespace App; use Swoft\SwoftApplication;
use function date_default_timezone_set; /**
* Class Application
*
* @since 2.0
*/
class Application extends SwoftApplication
{
protected function beforeInit(): void
{
parent::beforeInit(); // you can init php setting.
date_default_timezone_set('Asia/Shanghai'); // 设置时区
} /**
* @return array
*/
public function getCLoggerConfig(): array
{
$config = parent::getCLoggerConfig(); // False: Dont print log to terminal
$config['enable'] = true; return $config;
}
}
发现他继承 SwoftApplication 要执行父类的construct方法
进入 SwoftApplication 发现初始化方法
/**
* Class constructor.
*
* @param array $config
*/
public function __construct(array $config = [])
{
// Check runtime env 检查运行环境是否符合 php版本 swoole版本
SwoftHelper::checkRuntime(); // Storage as global static property. Swoft::$app = $this; // 当前对象赋值给 // Before init
$this->beforeInit(); // Init console logger
$this->initCLogger(); //初始化 打印到console界面的日志系统 // Can setting properties by array if ($config) {
ObjectHelper::init($this, $config); // 初始化配置
} // Init application
$this->init(); // 真真的初始化 // After init
$this->afterInit(); // 初始化完执行
}
进入 $this->init()
protected function init(): void
{
// Init system path aliases
$this->findBasePath(); // 找到当前基本路径
$this->setSystemAlias(); // 设置系统别名 $processors = $this->processors(); //重要 实例化几个进程 返回 $this->processor = new ApplicationProcessor($this); // 实例化$this->processor 也就是当前application运用的属性 后面会执行他的handel方法
$this->processor->addFirstProcessor(...$processors); // 把第一个processor添加到 $this->processors
}
/**
* @return ProcessorInterface[]
*/
protected function processors(): array
{
return [
new EnvProcessor($this), // 环境
new ConfigProcessor($this), // 配置
new AnnotationProcessor($this), // 注解
new BeanProcessor($this), // bean
new EventProcessor($this), // 事件
new ConsoleProcessor($this),
];
}
$this->processor = new ApplicationProcessor($this);
调用每个process的handel方法
/**
* Handle application processors
*/
public function handle(): bool
{
$disabled = $this->application->getDisabledProcessors();
foreach ($this->processors as $processor) {
$class = get_class($processor);
// If is disabled, skip handle.
if (isset($disabled[$class])) {
continue;
}
$processor->handle();
}
return true;
}
$this->processor->addFirstProcessor(...$processors); // 把这些对象都丢到$this->processors里面
public function addFirstProcessor(Processor ...$processor): bool
{
array_unshift($this->processors, ... $processor);
return true;
}
实例化 基本执行完成,开始run
// Run application
(new \App\Application())->run();
/**
* Run application
*/
public function run(): void
{
try {
if (!$this->beforeRun()) {
return;
}
$this->processor->handle();
} catch (Throwable $e) {
Console::colored(sprintf('%s(code:%d) %s', get_class($e), $e->getCode(), $e->getMessage()), 'red');
Console::colored('Code Trace:', 'comment');
echo $e->getTraceAsString(), "\n";
}
}
调用当前对象的 handle方法
public function handle(): bool
{
$disabled = $this->application->getDisabledProcessors();
foreach ($this->processors as $processor) {
$class = get_class($processor);
// If is disabled, skip handle.
if (isset($disabled[$class])) {
continue;
}
$processor->handle();
}
return true;
}
这个时候 将之前保存到$this->pkrocesssors里面的对象的handle方法执行一遍
初始化完成
p.p1 { margin: 0; font: 11px Menlo; color: rgba(0, 0, 0, 1); background-color: rgba(255, 255, 255, 1) }
span.s1 { font-variant-ligatures: no-common-ligatures }
string(29) "Swoft\Processor\BeanProcessor"
p.p1 { margin: 0; font: 11px Menlo; color: rgba(0, 0, 0, 1); background-color: rgba(255, 255, 255, 1) }
span.s1 { font-variant-ligatures: no-common-ligatures }
string(31) "Swoft\Processor\ConfigProcessor"
string(35) "Swoft\Processor\AnnotationProcessor"
p.p1 { margin: 0; font: 11px Menlo; color: rgba(0, 0, 0, 1); background-color: rgba(255, 255, 255, 1) }
span.s1 { font-variant-ligatures: no-common-ligatures }
string(28) "Swoft\Processor\EnvProcessor"
p.p1 { margin: 0; font: 11px Menlo; color: rgba(0, 0, 0, 1); background-color: rgba(255, 255, 255, 1) }
span.s1 { font-variant-ligatures: no-common-ligatures }
string(32) "Swoft\Processor\ConsoleProcessor"
代码位于framwork/processor
比如 执行beanprocessor 下面的handle方法 做了一大堆事情,好像是初始bean化容器 把注解 定义 解析等都挂到container的属性上去
BeanFactory::addDefinitions($definitions);
BeanFactory::addAnnotations($annotations);
BeanFactory::addParsers($parsers);
BeanFactory::setHandler($handler);
BeanFactory::init();
public static function addAnnotations(array $annotations): void
{
Container::getInstance()->addAnnotations($annotations);
}
public function addAnnotations(array $annotations): void
{
$this->annotations = ArrayHelper::merge($this->annotations, $annotations);
}
<?php declare(strict_types=1); namespace Swoft\Processor; use InvalidArgumentException;
use ReflectionException;
use Swoft\Annotation\AnnotationRegister;
use Swoft\Annotation\Exception\AnnotationException;
use Swoft\Bean\Annotation\Mapping\Bean;
use Swoft\Bean\BeanFactory;
use Swoft\Bean\Container;
use Swoft\BeanHandler;
use Swoft\Config\Config;
use Swoft\Contract\DefinitionInterface;
use Swoft\Helper\SwoftHelper;
use Swoft\Log\Helper\CLog;
use Swoft\Stdlib\Helper\ArrayHelper;
use function alias;
use function file_exists;
use function get_class;
use function sprintf; /**
* Class BeanProcessor
*
* @since 2.0
*/
class BeanProcessor extends Processor
{
/**
* Handle bean
*
* @return bool
* @throws ReflectionException
* @throws AnnotationException
*/
public function handle(): bool
{
if (!$this->application->beforeBean()) {
return false;
} $handler = new BeanHandler(); $definitions = $this->getDefinitions();
$parsers = AnnotationRegister::getParsers();
$annotations = AnnotationRegister::getAnnotations(); BeanFactory::addDefinitions($definitions); BeanFactory::addAnnotations($annotations);
BeanFactory::addParsers($parsers);
BeanFactory::setHandler($handler);
BeanFactory::init(); $stats = BeanFactory::getStats();
CLog::info('Bean is initialized(%s)', SwoftHelper::formatStats($stats)); /* @var Config $config */
$config = BeanFactory::getBean('config');
CLog::info('Config path is %s', $config->getPath()); if ($configEnv = $config->getEnv()) {
CLog::info('Config env=%s', $configEnv);
} else {
CLog::info('Config env is not setting');
} return $this->application->afterBean();
} /**
* Get bean definitions
*
* @return array
*/
private function getDefinitions(): array
{
// Core beans
$definitions = [];
$autoLoaders = AnnotationRegister::getAutoLoaders(); // get disabled loaders by application
$disabledLoaders = $this->application->getDisabledAutoLoaders(); foreach ($autoLoaders as $autoLoader) {
if (!$autoLoader instanceof DefinitionInterface) {
continue;
} $loaderClass = get_class($autoLoader); // If the component is disabled by app.
if (isset($disabledLoaders[$loaderClass])) {
CLog::info('Auto loader(%s) is <cyan>DISABLED</cyan>, skip handle it', $loaderClass);
continue;
} // If the component is disabled by self.
if (!$autoLoader->isEnable()) {
CLog::info('Auto loader(%s) is <cyan>DISABLED</cyan>, skip handle it', $loaderClass);
continue;
} $definitions = ArrayHelper::merge($definitions, $autoLoader->beans());
} // Application bean definitions
$beanFile = alias($this->application->getBeanFile()); if (!file_exists($beanFile)) {
throw new InvalidArgumentException(sprintf('The bean config file of %s is not exist!', $beanFile));
} /** @noinspection PhpIncludeInspection */
$beanDefinitions = require $beanFile; return ArrayHelper::merge($definitions, $beanDefinitions);
}
}
swoft运行流程的更多相关文章
- react-native start 运行流程
在CMD下键入 C:\Node_JS\MyAwesomeProject>react-native start 运行流程: C:\Users\Grart\AppData\Roaming\npm\r ...
- 1、CC2541蓝牙4.0芯片中级教程——基于OSAL操作系统的运行流程了解+定时器和串口例程了解
本文根据一周CC2541笔记汇总得来—— 适合概览和知识快速索引—— 全部链接: 中级教程-OSAL操作系统\OSAL操作系统-实验01 OSAL初探 [插入]SourceInsight-工程建立方法 ...
- java里的分支语句--程序运行流程的分类(顺序结构,分支结构,循环结构)
JAVA里面的程序运行流程分三大类: 1,顺序结构:顺序结构就是依次执行每一行代码 2,分支结构:分支结构就是按不同的条件进行分支 3,循环结构:一段代码依条件进行循环执行. 其中,分支结构有两大类: ...
- servlet运行流程
servlet运行流程 (2013-06-19 19:16:43) 转载▼ 首先Servlet被部署到Web容器中,当客户端发送调用这个Servlet的请求到达Web容器时,Web容器会先判 ...
- [原创]java WEB学习笔记70:Struts2 学习之路-- struts2拦截器源码分析,运行流程
本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...
- Struts2框架的运行流程
Struts2的运行流程 1.浏览器发送请求到控制器(如Struts2中的核心控制器StrutsPrepareAndExecuteFilter): 2.控制器调用Action的execute方法: 3 ...
- 转:[gevent源码分析] 深度分析gevent运行流程
[gevent源码分析] 深度分析gevent运行流程 http://blog.csdn.net/yueguanghaidao/article/details/24281751 一直对gevent运行 ...
- Struts2运行流程分析
一.Struts2运行流程图: 二.运行流程分析: 1. 请求发送给StrutsPrepareAndExecuteFilter 2.StrutsPrepareAndExecuteFilter询问Act ...
- Struts2的运行流程以及关键拦截器介绍
Struts2的运行流程 1.ActionProxy是Action的一个代理类,也就是说Action的调用是通过ActionProxy实现的,其实就是调用了ActionProxy.execute()方 ...
随机推荐
- 第23课 - #error 和 #line 使用分析
第23课 - #error 和 #line 使用分析 1. #error 的用法 (1)#error 是一个预处理器指示字,用于生成一个编译错误消息,这个消息最终会传递到编译器(gcc) 在思考这一点 ...
- Java常见重构技巧 - 去除不必要的!=null判断空的5种方式,很少有人知道后两种
常见重构技巧 - 去除不必要的!= 项目中会存在大量判空代码,多么丑陋繁冗!如何避免这种情况?我们是否滥用了判空呢?@pdai 常见重构技巧 - 去除不必要的!= 场景一:null无意义之常规判断空 ...
- apache-apollo启动报错
启动Apollo后,进入网页版管理中心后报错:500: Server Error https://127.0.0.1:61681/console/index.html 网页抓包 报错:{"c ...
- hystrix文档翻译之metrics
metrics和监控 动机 HystrixCommands和HystrixObservableCommands执行过程中会产生相关运行情况的metrics.这些metrics对于监控系统表现有很大的 ...
- 微信小程序直播接入
申请开通小程序直播 1.申请小程序直播有以下几个硬性指标: 1. 满足小程序18个开放类目 2. 主体下小程序近半年没有严重违规 3. 小程序近90天内有过支付行为 4. 主体下公众号累计粉丝数大于1 ...
- golang 条件语句 for range 分析
for range 作为 golang中的语法糖提供了便利操作; 对于for range 支持 的数据类型包含: 数组以及指向数组的指针 切片 字典 通道 字符串 在range的语法糖中提供了一下特殊 ...
- Element-UI:级联选择器:Cannot read property 'level' of null"
当级联选择时如果其选择内容需要动态变化时,如果没有选择就不会报错的:而当做出选择后又要动态变化级联选择器内容时,就会报错/ 错误:这个错误的原因是当选择后,再更新内容时,选择器仍会关联原来的数据,导致 ...
- java学习从“菜鸟”到“放弃”
今天学到java的对象和类中, 由于刚考完c++面向对象与程序设计这门课,对于c++中的类掌握自认为不错,就开始过渡到java. 今天面对的问题,在书写一个类的时候,发现了许多与c++不同的地方. 比 ...
- 关于KeePass实现ssh协议的自动登录
本文主要介绍一下,在keepass中如何实现linux主机的ssh方式的自动登录 keepass版本:KeePass 2.45 在keepass的URL中,其实默认也是内置了ssh的,其原理是调用pu ...
- JVM学习(六)JVM常见知识问答
文章更新时间:2020/04/21 1.什么是Java虚拟机?为什么Java被称作是"平台无关的编程语言"? Java虚拟机是一个可以执行Java字节码的虚拟机进程. Java源文 ...