源码阅读 - 初始 : (2) 初始化 App
加载机制
公共文件入口
public/index.php
bootstrap/autoload.php
自动加载机制
vendor/autoload.php
加载 composer 扩展包的自动加载机制
storage/framework/compiled.php
如果存在编译文件则加载编译文件
bootstrap/app.php
创建 `$app` = new Illuminate\\Foundation\\Application
注册基础绑定 registerBaseBindings
实例化 app
实例化 Illuminate\\Container\\Container
注册基础服务绑定 registerBaseServiceProviders
注册 事件绑定
注册 路由绑定
注册核心容器 alias 关联 registerCoreContainerAliases
App\\Http\\Kernel
App\\Console\\Kernel
App\\Exceptions\\Handler
kernel 的处理
- 创建 `kernel`
- 创建 `response`
- 发出 `response`
- 终止 `kernel`
初始化 Application
根据指定的路径来初始化应用, 原始码
php
$app = new Illuminate\\Foundation\\Application(
realpath(__DIR__ . '/../')
);
Illuminate/Foundation/Application::__construct()
php
// 1) 注册基本绑定
$this->registerBaseBindings();
// 2) 注册服务提供者
// 如果存在 register 方法, 则执行并且标记为已经注册过. 如果系统已经启动, 则直接运行 boot 方法
$this->registerBaseServiceProviders();
// 3) 注册核心 Alias
$this->registerCoreContainerAliases();
1) 注册基本绑定
php
# 1) 实例化 app
$this->instance('app', $this);
# 实例化 container => app
$this->instance(Container::class, $this);
# 2) 实例化 PackageManifest
$this->instance(PackageManifest::class, new PackageManifest(...));
1-1) 实例化 app
实例化 App[Application::instance()]
这里拿 ('app', $this)
为例子来阅读源码
php
// 移除抽象关联
$this->removeAbstractAlias($abstract);
// 确定给定的抽象类型是否已经绑定
// 已经设定 Alias
$isBound = $this->bound($abstract);
// 移除关联
unset($this->aliases[$abstract]);
// 检测此类型是否被绑定过, 如果已经绑定会重新触发绑定并且更新类
// 实例化 instances['app'] = $this
$this->instances[$abstract] = $instance;
// 重新绑定
if ($isBound) {
$this->rebound($abstract);
// 1) make -> alias (resolve)
# $this->make($abstract)
// 触发回调
# foreach ($this->getReboundCallbacks($abstract) as $callback) {
# call_user_func($callback, $this, $instance);
# }
}
1-2) 实例化 PackageManifest
2) 注册事件处理
php
// 注册事件处理器
$this->register(new EventServiceProvider($this));
// 注册日志服务
$this->register(new LogServiceProvider($this));
// 注册路由服务
$this->register(new RoutingServiceProvider($this));
2-1) Application::register() 方法
php
/* sample service providers
$this->serviceProviders = [
Illuminate\\Events\\EventServiceProvider Object
Illuminate\\Log\\LogServiceProvider Object
Illuminate\\Routing\\RoutingServiceProvider Object
];
*/
// 获取注册的对象, 传递($provider) 可以是对象/字串
if (($registered = $this->getProvider($provider)) && ! $force) {
return $registered;
}
// 如果给定的 provider 是字串, 则返回实例化的对象.
if (is_string($provider)) {
$provider = $this->resolveProvider($provider);
# new $provider($this)
}
// 检测给定的对象是否存在 register 方法, 存在则执行 register 方法并标注为已注册
if (method_exists($provider, 'register')) {
$provider->register();
}
$this->markAsRegistered($provider);
// todo - 什么时候启动
// 如果应用已经启动, 我们便有机会启动 ServiceProvider 的 boot 逻辑, 便于开发者持续开发
if ($this->booted) {
$this->bootProvider($provider);
# 启动 boot 方法
# if (method_exists($provider, 'boot')) {
# return $this->call([$provider, 'boot']);
# }
}
return $provider;
2-2) EventServiceProvider
// 注册事件触发器, 并且配置队列执行
$this->app->singleton('events', function ($app) {
return (new Dispatcher($app))->setQueueResolver(function () use ($app) {
return $app->make(QueueFactoryContract::class);
});
});
2-3) LogServiceProvider
// 注册日志
$this->app->singleton('log', function () {
return $this->createLogger();
});
2-4) RoutingServiceProvider
// 注册路由
$this->registerRouter();
// url 生成
$this->registerUrlGenerator();
// 定向器
$this->registerRedirector();
// psr 请求
$this->registerPsrRequest();
// psr 响应
$this->registerPsrResponse();
// 响应工厂
$this->registerResponseFactory();
// 控制器触发器
$this->registerControllerDispatcher();
3) 注册 Alias
将指定的类和 app 示例做绑定
php
$allAlias = [
'app' => [
\\Illuminate\\Foundation\\Application::class,
\\Illuminate\\Contracts\\Container\\Container::class,
\\Illuminate\\Contracts\\Foundation\\Application::class,
\\Psr\\Container\\ContainerInterface::class
],
...
'view' => [
\\Illuminate\\View\\Factory::class,
\\Illuminate\\Contracts\\View\\Factory::class
],
];
foreach($allAlias = as $key => $aliases) {
foreach ($aliases as $alias) {
// key : app
// alias : Illuminate\\Foundation\\Application::class
$this->alias($key, $alias);
}
}
3-1) 系统 alias 项目
php
$alias = [
'app' => [
\\Illuminate\\Foundation\\Application::class,
\\Illuminate\\Contracts\\Container\\Container::class,
\\Illuminate\\Contracts\\Foundation\\Application::class,
\\Psr\\Container\\ContainerInterface::class
],
'auth' => [
\\Illuminate\\Auth\\AuthManager::class,
\\Illuminate\\Contracts\\Auth\\Factory::class
],
'auth.driver' => [
\\Illuminate\\Contracts\\Auth\\Guard::class
],
'blade.compiler' => [
\\Illuminate\\View\\Compilers\\BladeCompiler::class
],
'cache' => [
\\Illuminate\\Cache\\CacheManager::class,
\\Illuminate\\Contracts\\Cache\\Factory::class
],
'cache.store' => [
\\Illuminate\\Cache\\Repository::class,
\\Illuminate\\Contracts\\Cache\\Repository::class
],
'config' => [
\\Illuminate\\Config\\Repository::class,
\\Illuminate\\Contracts\\Config\\Repository::class
],
'cookie' => [
\\Illuminate\\Cookie\\CookieJar::class,
\\Illuminate\\Contracts\\Cookie\\Factory::class,
\\Illuminate\\Contracts\\Cookie\\QueueingFactory::class
],
'encrypter' => [
\\Illuminate\\Encryption\\Encrypter::class,
\\Illuminate\\Contracts\\Encryption\\Encrypter::class
],
'db' => [
\\Illuminate\\Database\\DatabaseManager::class
],
'db.connection' => [
\\Illuminate\\Database\\Connection::class, \\Illuminate\\Database\\ConnectionInterface::class
],
'events' => [
\\Illuminate\\Events\\Dispatcher::class,
\\Illuminate\\Contracts\\Events\\Dispatcher::class
],
'files' => [
\\Illuminate\\Filesystem\\Filesystem::class
],
'filesystem' => [
\\Illuminate\\Filesystem\\FilesystemManager::class,
\\Illuminate\\Contracts\\Filesystem\\Factory::class
],
'filesystem.disk' => [
\\Illuminate\\Contracts\\Filesystem\\Filesystem::class
],
'filesystem.cloud' => [
\\Illuminate\\Contracts\\Filesystem\\Cloud::class
],
'hash' => [
\\Illuminate\\Contracts\\Hashing\\Hasher::class
],
'translator' => [
\\Illuminate\\Translation\\Translator::class,
\\Illuminate\\Contracts\\Translation\\Translator::class
],
'log' => [
\\Illuminate\\Log\\Writer::class,
\\Illuminate\\Contracts\\Logging\\Log::class, \\Psr\\Log\\LoggerInterface::class
],
'mailer' => [
\\Illuminate\\Mail\\Mailer::class,
\\Illuminate\\Contracts\\Mail\\Mailer::class,
\\Illuminate\\Contracts\\Mail\\MailQueue::class
],
'auth.password' => [
\\Illuminate\\Auth\\Passwords\\PasswordBrokerManager::class,
\\Illuminate\\Contracts\\Auth\\PasswordBrokerFactory::class
],
'auth.password.broker' => [
\\Illuminate\\Auth\\Passwords\\PasswordBroker::class,
\\Illuminate\\Contracts\\Auth\\PasswordBroker::class
],
'queue' => [
\\Illuminate\\Queue\\QueueManager::class,
\\Illuminate\\Contracts\\Queue\\Factory::class,
\\Illuminate\\Contracts\\Queue\\Monitor::class
],
'queue.connection' => [
\\Illuminate\\Contracts\\Queue\\Queue::class
],
'queue.failer' => [
\\Illuminate\\Queue\\Failed\\FailedJobProviderInterface::class
],
'redirect' => [
\\Illuminate\\Routing\\Redirector::class
],
'redis' => [
\\Illuminate\\Redis\\RedisManager::class,
\\Illuminate\\Contracts\\Redis\\Factory::class
],
'request' => [
\\Illuminate\\Http\\Request::class, \\Symfony\\Component\\HttpFoundation\\Request::class
],
'router' => [
\\Illuminate\\Routing\\Router::class,
\\Illuminate\\Contracts\\Routing\\Registrar::class,
\\Illuminate\\Contracts\\Routing\\BindingRegistrar::class
],
'session' => [
\\Illuminate\\Session\\SessionManager::class
],
'session.store' => [
\\Illuminate\\Session\\Store::class,
\\Illuminate\\Contracts\\Session\\Session::class
],
'url' => [
\\Illuminate\\Routing\\UrlGenerator::class,
\\Illuminate\\Contracts\\Routing\\UrlGenerator::class
],
'validator' => [
\\Illuminate\\Validation\\Factory::class,
\\Illuminate\\Contracts\\Validation\\Factory::class
],
'view' => [
\\Illuminate\\View\\Factory::class,
\\Illuminate\\Contracts\\View\\Factory::class
],
];
3-2) alias 结果
php
/* $this->aliases = [
[Illuminate\\Foundation\\Application] => app
[Illuminate\\Contracts\\Container\\Container] => app
[Illuminate\\Contracts\\Foundation\\Application] => app
[Psr\\Container\\ContainerInterface] => app
[Illuminate\\Auth\\AuthManager] => auth
[Illuminate\\Contracts\\Auth\\Factory] => auth
...
]
*/
singleton Kernel 和异常处理
原始代码
step 01:singleton
php
$app->singleton(
Illuminate\\Contracts\\Http\\Kernel::class,
App\\Http\\Kernel::class
);
step 02:bind
// 抽象类绑定到实体类
$this->bind($abstract, $concrete, true);
step 03:bind code
// 如果没有给定实体类型, 我们简单设置实体类型为虚拟类型, 在那之后
// 在此之后,将注册为共享的具体类型,而不需要在两个参数中强制声明它们的类
$this->dropStaleInstances($abstract);
if (is_null($concrete)) {
$concrete = $abstract;
}
// 如果工厂不是闭包,这意味着它只是一个类名,它被绑定到这个容器中
// 我们把抽象类型包装在它自己的闭包中,以便在扩展时给我们更多的便利。
if (! $concrete instanceof Closure) {
$concrete = $this->getClosure($abstract, $concrete);
}
$this->bindings[$abstract] = compact('concrete', 'shared');
// 如果这个类型已经存在, 我们触发重新绑定
if ($this->resolved($abstract)) {
$this->rebound($abstract);
}
说明
创建时间: 2023-01-15 00:32:00 , 最后编辑于 2023-12-21 12:12:00