版权声明:转载请注明来源 https://blog.csdn.net/u013702678/article/details/82722195
经过前面两篇文章的分析,我们分析到了Provider启动时初始化Consumser的地方,也就是initConsumer过程,我们继续分析。
public function initConsumer()
{
//初始consumer,其中app_name表示Provider应用名称信息,而app_src表示应用所在的Bootstrap文件路径信息的上级目录,也就是用demo为列则是dubbo-php-framework-master/demo/demo-provider目录
$app_setting = array('app_name' => $this->processName, 'app_src' => dirname($this->requireFile));
//调用FSOFConsumer的init接口
FSOFConsumer::init($app_setting);
}
namespace com\fenqile\fsof\consumer;
use com\fenqile\fsof\consumer\proxy\ProxyFactory;
class FSOFConsumer
{
/**
* @var boolean Has [FSOFConsumer::init] been called?
*/
protected static $_init = FALSE;//标记FSOFConsumer是否已经初始化
protected static $_initSetting;//调用时上面调用时传入的信息,也即app_name和app_src信息
public static function init(array $settings = NULL)
{
if (self::isConsumerInit())//判断是否已经初始化
{
// Do not allow execution twice
return;
}
\Logger::getLogger(__CLASS__)->info("consumer cfg:".json_encode($settings, true));
$consumerRoot = __DIR__;//当前目录,也就是dubbo-php-framework-master/consumer
$fsofBootPath = dirname($consumerRoot);//当前目录的上级目录,也就是dubbo-php-framework-master目录
//加载commom,fsofCommonPath的路径为dubbo-php-framework-master/common
$fsofCommonPath = $fsofBootPath.DIRECTORY_SEPARATOR.'common';
require_once($fsofCommonPath.DIRECTORY_SEPARATOR.'BootStrap.php');//加载common目录下的BootStrap文件,而common下的BootStrap.php文件会加载common下所有相关文件,这里后续再分析。
//加载registry,fsofRegistryPaht的路径为dubbo-php-framework-master/registray
$fsofRegistryPath = $fsofBootPath.DIRECTORY_SEPARATOR.'registry';
require_once($fsofRegistryPath.DIRECTORY_SEPARATOR.'BootStrap.php');//加载registray目录下的BootStrap文件,这个BootStrap文件会加载registry下的所有相关文件,这里后续再分析。
//检查输入参数app_src和app_name
if ((!isset($settings['app_src'])) || (!isset($settings['app_name'])))
{
throw new \Exception("FSOFConsumer::init传入的app的src路径参数不准确");
}
//获取消费端consumer配置文件
$consumerConfigFile = $settings['app_src'];
$consumerConfigFile = rtrim($consumerConfigFile, DIRECTORY_SEPARATOR);//从最右边的开始的/删除路径信息,这里操作完后的路径为dubbo-php-framework-master/demo
$consumerConfigFile = $consumerConfigFile.DIRECTORY_SEPARATOR.'consumer'.DIRECTORY_SEPARATOR.$settings['app_name'].'.consumer';//拼接consumer文件路径,不过这里的和开源处理的项目目录对比,拼接是错误的,还少一级目录,以demo应用为列,consumer文件的路径为dubbo-php-framework-master/demo/demo-consumer/consumer/demo-consumer.consumer
if (file_exists($consumerConfigFile))//判断文件路径是否存在
{
try
{
$consumerConfig = parse_ini_file($consumerConfigFile, true);//解析文件路径
}
catch (\Exception $e)
{
throw new \Exception("consumer配置文件有误[".$consumerConfigFile."]");
}
}
else
{
$consumerConfig = array();
}
self::$_initSetting = $settings;
//注册consumer框架的autoLoader
self::registerConsumerFrameAutoLoader($consumerRoot);
//注册consumer的动态代理工厂
ProxyFactory::setConsumerConfig($consumerConfig, $consumerConfigFile, $settings);
//FSOFConsumer is now initialized
self::$_init = TRUE;
}
private static function registerConsumerFrameAutoLoader($consumerRoot)
{
if (!self::isConsumerInit())
{
//注册框架顶层命名空间到自动加载器
require_once $consumerRoot.DIRECTORY_SEPARATOR.'FrameAutoLoader.php';
FrameAutoLoader::setRootNS('com\fenqile\fsof\consumer', $consumerRoot);
FrameAutoLoader::setRootNS('com\fenqile\fsof\consumer\app', $consumerRoot.DIRECTORY_SEPARATOR.'app');
FrameAutoLoader::setRootNS('com\fenqile\fsof\consumer\fsof', $consumerRoot.DIRECTORY_SEPARATOR.'fsof');
FrameAutoLoader::setRootNS('com\fenqile\fsof\consumer\proxy', $consumerRoot.DIRECTORY_SEPARATOR.'proxy');
FrameAutoLoader::setRootNS('com\fenqile\fsof\consumer\client', $consumerRoot.DIRECTORY_SEPARATOR.'client');
//利用PHP自带的spl_autoload_register注册PHP文件自动加载
spl_autoload_register(__NAMESPACE__.'\FrameAutoLoader::autoload');
}
}
public static function getInitSetting()
{
return self::$_initSetting;
}
public static function isConsumerInit()
{
return self::$_init;
}
}
class FrameAutoLoader
{
/**
* 命名空间的路径
*/
private static $nsPath = Array();
/**
* 自动载入类
* @param $class
*/
public static function autoload($class)
{
$frameRootPathDepth = count(explode('\\', __NAMESPACE__));
$root = explode('\\', trim($class, '\\'));
$pathDepth = count($root);
if($pathDepth > $frameRootPathDepth)
{
$key = $className = $class;
if($pathDepth > $frameRootPathDepth + 1)
{
$root = explode('\\', trim($class, '\\'), $frameRootPathDepth + 2);
$className = $root[$frameRootPathDepth + 1];
unset($root[$frameRootPathDepth + 1]);
$key = implode($root, '\\');
}
else if($pathDepth == $frameRootPathDepth + 1)
{
$root = explode('\\', trim($class, '\\'), $frameRootPathDepth + 1);
$className = $root[$frameRootPathDepth];
unset($root[$frameRootPathDepth]);
$key = implode($root, '\\');
}
if(isset(self::$nsPath[$key]))
{
include_once self::$nsPath[$key] . DIRECTORY_SEPARATOR . str_replace('\\', DIRECTORY_SEPARATOR, $className) . '.php';
}
}
}
/**
* 设置根命名空间
* @param $root
* @param $path
*/
public static function setRootNS($root, $path)
{
self::$nsPath[$root] = $path;
}
}