分析一下get
方法源码,
public function get($id)
{
// 如果解析过,则直接返回
if (isset($this->resolvedEntries[$id]) || array_key_exists($id, $this->resolvedEntries)) {
return $this->resolvedEntries[$id];
}
return $this->resolvedEntries[$id] = $this->make($id);
}
上面可以看出,首次解析不走if
,查看make
方法,
public function make(string $name, array $parameters = [])
{
$definition = $this->getDefinition($name);
if (! $definition) {
throw new NotFoundException("No entry or class found for '{$name}'");
}
return $this->resolveDefinition($definition, $parameters);
}
前面绑定阶段,已经将ApplicationInterface
绑定到Hyperf\Framework\ApplicationFactory
类上,通过DefinitionSource
类,将对应实现转换成对应DefinitionInterface
接口的实现类。
// 调用逻辑
public function __construct(array $source)
{
$this->source = $this->normalizeSource($source);
}
protected function normalizeSource(array $source): array
{
$definitions = [];
foreach ($source as $identifier => $definition) {
$normalizedDefinition = $this->normalizeDefinition($identifier, $definition);
if (! is_null($normalizedDefinition)) {
$definitions[$identifier] = $normalizedDefinition;
}
}
return $definitions;
}
protected function normalizeDefinition(string $identifier, $definition): ?DefinitionInterface
{
if ($definition instanceof PriorityDefinition) {
$definition = $definition->getDefinition();
}
if (is_string($definition) && class_exists($definition)) {
if (method_exists($definition, '__invoke')) {
return new FactoryDefinition($identifier, $definition, []);
}
return $this->autowire($identifier, new ObjectDefinition($identifier, $definition));
}
if (is_callable($definition)) {
return new FactoryDefinition($identifier, $definition, []);
}
return null;
}
查看ApplicationFactory
类,存在__invoke
方法,返回的是一个FactoryDefinition
对象。 ![](image https://oss.xiaokeaii.top/2024/applicationFactory.png)
$definition = $this->getDefinition($name);
所以这行返回的是一个FactoryDefinition
对象。打印结果如下, ![](image https://oss.xiaokeaii.top/2024/工厂定义.png )
resolveDefinition方法
继续分析,查看resolveDefinition
方法,
文件位置: /vendor/hyperf/di/src/Container.php
protected function resolveDefinition(DefinitionInterface $definition, array $parameters = [])
{
return $this->definitionResolver->resolve($definition, $parameters);
}
上面可以看到,这里调用了解析调度器ResolverDispatcher
的resolve
方法。
resolve方法
文件位置:/vendor/hyperf/di/src/Resolver/ResolverDispatcher.php
public function resolve(DefinitionInterface $definition, array $parameters = [])
{
if ($definition instanceof SelfResolvingDefinitionInterface) {
return $definition->resolve($this->container);
}
$guard = DepthGuard::getInstance();
return $guard->call(
$definition->getName(),
fn () => $this->getDefinitionResolver($definition)->resolve($definition, $parameters)
);
}
这里FactoryDefinition
不是SelfResolvingDefinitionInterface
接口的实现类,所以不走if
。 $guard
是DepthGuard
类的实例,调用call
方法,
call方法
文件位置:/vendor/hyperf/di/src/Resolver/DepthGuard.php
public function call(string $name, callable $callable)
{
try {
$this->increment();
return $callable();
} catch (CircularDependencyException $exception) {
$exception->addDefinitionName($name);
throw $exception;
} finally {
$this->decrement();
}
}
这里最终执行传入的闭包,回到上面,执行闭包。 查看闭包执行源码,
./vendor/hyperf/di/src/Resolver/ResolverDispatcher.php
getDefinitionResolver方法
private function getDefinitionResolver(DefinitionInterface $definition): ResolverInterface
{
return match (true) {
$definition instanceof ObjectDefinition => $this->objectResolver ??= new ObjectResolver($this->container, $this),
$definition instanceof FactoryDefinition => $this->factoryResolver ??= new FactoryResolver($this->container, $this),
default => throw new RuntimeException('No definition resolver was configured for definition of type ' . get_class($definition)),
};
}
从代码可知,这里会根据DefinitionInterface
的实现类,将对应解析器赋值给成员变量。 这里传进来的是FactoryDefinition
类,所以会执行第二条。 紧接着调用FactoryResolver
类的resolve
方法。
resolve方法
文件位置:/vendor/hyperf/di/src/Resolver/FactoryResolver.php
public function resolve(DefinitionInterface $definition, array $parameters = [])
{
$callable = null;
try {
$callable = $definition->getFactory();
if (! method_exists($callable, '__invoke')) {
throw new NotCallableException();
}
if (is_string($callable)) {
$callable = $this->container->get($callable);
}
return $callable($this->container, $parameters);
} catch (NotCallableException $e) {
// Custom error message to help debugging
if (is_string($callable) && class_exists($callable) && method_exists($callable, '__invoke')) {
throw new InvalidDefinitionException(sprintf('Entry "%s" cannot be resolved: factory %s. Invokable classes cannot be automatically resolved if autowiring is disabled on the container, you need to enable autowiring or define the entry manually.', $definition->getName(), $e->getMessage()));
}
throw new InvalidDefinitionException(sprintf('Entry "%s" cannot be resolved: factory %s', $definition->getName(), $e->getMessage()));
}
}
分析该方法,$callable
是工厂的类名,如果传递过来的是字符串,则通过容器解析出对应的类,方法同理,不再赘述。 最终调用该工厂类的__invoke
方法返回解析结果。