启动命令 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'; SwooleCoroutine::set([ 'max_coroutine' => 300000, ]); // Run application (new AppApplication())->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 SwoftSwoftApplication; 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 AppApplication())->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(), " ";
}
}
调用当前对象的 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方法执行一遍
初始化完成
string(29) "SwoftProcessorBeanProcessor"
string(31) "SwoftProcessorConfigProcessor"
string(35) "SwoftProcessorAnnotationProcessor"
string(28) "SwoftProcessorEnvProcessor"
string(32) "SwoftProcessorConsoleProcessor"
代码位于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 SwoftProcessor; use InvalidArgumentException; use ReflectionException; use SwoftAnnotationAnnotationRegister; use SwoftAnnotationExceptionAnnotationException; use SwoftBeanAnnotationMappingBean; use SwoftBeanBeanFactory; use SwoftBeanContainer; use SwoftBeanHandler; use SwoftConfigConfig; use SwoftContractDefinitionInterface; use SwoftHelperSwoftHelper; use SwoftLogHelperCLog; use SwoftStdlibHelperArrayHelper; 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); } }