Moved loadAspects to Scanner.

This commit is contained in:
李铭昕 2020-05-22 18:19:32 +08:00
parent dad2342f91
commit 30af4172b4
5 changed files with 89 additions and 68 deletions

View File

@ -15,6 +15,11 @@ use Hyperf\Config\ProviderConfig;
final class ScanConfig
{
/**
* @var string
*/
private $configDir;
/**
* The paths should be scaned everytime.
*
@ -53,6 +58,7 @@ final class ScanConfig
private static $instance;
public function __construct(
string $configDir,
array $paths = [],
array $dependencies = [],
array $ignoreAnnotations = [],
@ -60,6 +66,7 @@ final class ScanConfig
array $collectors = [],
array $classMap = []
) {
$this->configDir = $configDir;
$this->paths = $paths;
$this->dependencies = $dependencies;
$this->ignoreAnnotations = $ignoreAnnotations;
@ -68,6 +75,11 @@ final class ScanConfig
$this->classMap = $classMap;
}
public function getConfigDir(): string
{
return $this->configDir;
}
public function getPaths(): array
{
return $this->paths;
@ -104,9 +116,10 @@ final class ScanConfig
return self::$instance;
}
[$config, $serverDependencies] = static::initConfigByFile(BASE_PATH . '/config');
[$config, $serverDependencies] = static::initConfigByFile($configDir = BASE_PATH . '/config');
return self::$instance = new self(
$configDir,
$config['paths'] ?? [],
$serverDependencies ?? [],
$config['ignore_annotations'] ?? [],

View File

@ -11,10 +11,12 @@ declare(strict_types=1);
*/
namespace Hyperf\Di\Annotation;
use Hyperf\Config\ProviderConfig;
use Hyperf\Di\BetterReflectionManager;
use Hyperf\Di\ClassLoader;
use Hyperf\Di\MetadataCollector;
use Hyperf\Utils\Filesystem\Filesystem;
use ReflectionProperty;
use Roave\BetterReflection\Reflection\Adapter;
use Roave\BetterReflection\Reflection\ReflectionClass;
@ -110,7 +112,7 @@ class Scanner
}
$annotationReader = new AnnotationReader();
$lastModified = $this->deserializeCachedCollectors($collectors);
$lastCacheModified = $this->deserializeCachedCollectors($collectors);
$paths = $this->normalizeDir($paths);
@ -122,7 +124,7 @@ class Scanner
}
foreach ($classes as $reflectionClass) {
if ($this->filesystem->lastModified($reflectionClass->getFileName()) > $lastModified) {
if ($this->filesystem->lastModified($reflectionClass->getFileName()) > $lastCacheModified) {
/** @var MetadataCollector $collector */
foreach ($collectors as $collector) {
$collector::clear($reflectionClass->getName());
@ -132,6 +134,8 @@ class Scanner
}
}
$this->loadAspects($lastCacheModified);
$data = [];
/** @var MetadataCollector $collector */
foreach ($collectors as $collector) {
@ -179,4 +183,67 @@ class Scanner
return $this->filesystem->lastModified($this->path);
}
/**
* Load aspects to AspectCollector by configuration files and ConfigProvider.
*/
protected function loadAspects(int $lastCacheModified): void
{
$configDir = $this->scanConfig->getConfigDir();
if (! $configDir) {
return;
}
if ($lastCacheModified > $this->filesystem->lastModified($configDir . '/autoload/aspects.php')
&& $lastCacheModified > $this->filesystem->lastModified($configDir . '/config.php')
) {
return;
}
$aspects = require $configDir . '/autoload/aspects.php';
$baseConfig = require $configDir . '/config.php';
$providerConfig = ProviderConfig::load();
if (! isset($aspects) || ! is_array($aspects)) {
$aspects = [];
}
if (! isset($baseConfig['aspects']) || ! is_array($baseConfig['aspects'])) {
$baseConfig['aspects'] = [];
}
if (! isset($providerConfig['aspects']) || ! is_array($providerConfig['aspects'])) {
$providerConfig['aspects'] = [];
}
$aspects = array_merge($providerConfig['aspects'], $baseConfig['aspects'], $aspects);
foreach ($aspects ?? [] as $key => $value) {
if (is_numeric($key)) {
$aspect = $value;
$priority = null;
} else {
$aspect = $key;
$priority = (int) $value;
}
// Create the aspect instance without invoking their constructor.
$reflectionClass = BetterReflectionManager::reflectClass($aspect);
$properties = $reflectionClass->getImmediateProperties(ReflectionProperty::IS_PUBLIC);
$instanceClasses = $instanceAnnotations = [];
$instancePriority = null;
foreach ($properties as $property) {
if ($property->getName() === 'classes') {
$instanceClasses = $property->getDefaultValue();
} elseif ($property->getName() === 'annotations') {
$instanceAnnotations = $property->getDefaultValue();
} elseif ($property->getName() === 'priority') {
$instancePriority = $property->getDefaultValue();
}
}
$classes = $instanceClasses ?: [];
// Annotations
$annotations = $instanceAnnotations ?: [];
// Priority
$priority = $priority ?: ($instancePriority ?? null);
// Save the metadata to AspectCollector
// TODO: When the aspect removed from config, it should removed from AspectCollector.
AspectCollector::setAround($aspect, $classes, $annotations, $priority);
}
}
}

View File

@ -11,12 +11,10 @@ declare(strict_types=1);
*/
namespace Hyperf\Di\Aop;
use Hyperf\Config\ProviderConfig;
use Hyperf\Di\Annotation\AnnotationCollector;
use Hyperf\Di\Annotation\AspectCollector;
use Hyperf\Di\BetterReflectionManager;
use Hyperf\Utils\Filesystem\Filesystem;
use ReflectionProperty;
use Roave\BetterReflection\Reflection\ReflectionClass;
class ProxyManager
@ -50,12 +48,10 @@ class ProxyManager
public function __construct(
array $reflectionClassMap = [],
array $composerLoaderClassMap = [],
string $proxyDir = '',
string $configDir = ''
string $proxyDir = ''
) {
$this->proxyDir = $proxyDir;
$this->filesystem = new Filesystem();
$this->loadAspects($configDir);
$reflectionClassMap && $reflectionClassProxies = $this->generateProxyFiles($this->initProxiesByReflectionClassMap($reflectionClassMap));
$composerLoaderClassMap && $composerLoaderProxies = $this->generateProxyFiles($this->initProxiesByComposerClassMap($composerLoaderClassMap));
$this->proxies = array_merge($reflectionClassProxies, $composerLoaderProxies);
@ -251,59 +247,4 @@ class ProxyManager
}
return $defined;
}
/**
* Load aspects to AspectCollector by configuration files and ConfigProvider.
*/
protected function loadAspects(string $configDir): void
{
if (! $configDir) {
return;
}
$aspects = require $configDir . 'autoload/aspects.php';
$baseConfig = require $configDir . 'config.php';
$providerConfig = ProviderConfig::load();
if (! isset($aspects) || ! is_array($aspects)) {
$aspects = [];
}
if (! isset($baseConfig['aspects']) || ! is_array($baseConfig['aspects'])) {
$baseConfig['aspects'] = [];
}
if (! isset($providerConfig['aspects']) || ! is_array($providerConfig['aspects'])) {
$providerConfig['aspects'] = [];
}
$aspects = array_merge($providerConfig['aspects'], $baseConfig['aspects'], $aspects);
foreach ($aspects ?? [] as $key => $value) {
if (is_numeric($key)) {
$aspect = $value;
$priority = null;
} else {
$aspect = $key;
$priority = (int) $value;
}
// Create the aspect instance without invoking their constructor.
$reflectionClass = BetterReflectionManager::reflectClass($aspect);
$properties = $reflectionClass->getImmediateProperties(ReflectionProperty::IS_PUBLIC);
$instanceClasses = $instanceAnnotations = [];
$instancePriority = null;
foreach ($properties as $property) {
if ($property->getName() === 'classes') {
$instanceClasses = $property->getDefaultValue();
} elseif ($property->getName() === 'annotations') {
$instanceAnnotations = $property->getDefaultValue();
} elseif ($property->getName() === 'priority') {
$instancePriority = $property->getDefaultValue();
}
}
$classes = $instanceClasses ?: [];
// Annotations
$annotations = $instanceAnnotations ?: [];
// Priority
$priority = $priority ?: ($instancePriority ?? null);
// Save the metadata to AspectCollector
AspectCollector::setAround($aspect, $classes, $annotations, $priority);
}
}
}

View File

@ -62,7 +62,7 @@ trait ProxyTrait
return $map;
}
private static function handleAround(ProceedingJoinPoint $proceedingJoinPoint)
protected static function handleAround(ProceedingJoinPoint $proceedingJoinPoint)
{
$className = $proceedingJoinPoint->className;
$methodName = $proceedingJoinPoint->methodName;
@ -93,7 +93,7 @@ trait ProxyTrait
});
}
private static function makePipeline(): Pipeline
protected static function makePipeline(): Pipeline
{
$container = ApplicationContext::getContainer();
if (method_exists($container, 'make')) {
@ -104,7 +104,7 @@ trait ProxyTrait
return $pipeline;
}
private static function getClassesAspects(string $className, string $method): array
protected static function getClassesAspects(string $className, string $method): array
{
$aspects = AspectCollector::get('classes', []);
$matchedAspect = [];
@ -120,7 +120,7 @@ trait ProxyTrait
return $matchedAspect;
}
private static function getAnnotationAspects(string $className, string $method): array
protected static function getAnnotationAspects(string $className, string $method): array
{
$matchedAspect = $annotations = $rules = [];

View File

@ -46,7 +46,7 @@ class ClassLoader
timepoint('Scan');
// Get the class map of Composer loader
$composerLoaderClassMap = $this->getComposerClassLoader()->getClassMap();
$proxyManager = new ProxyManager($reflectionClassMap, $composerLoaderClassMap, $proxyFileDir, $configDir);
$proxyManager = new ProxyManager($reflectionClassMap, $composerLoaderClassMap, $proxyFileDir);
timepoint('InitProxyManager');
$this->proxies = $proxyManager->getProxies();
}