diff --git a/src/config/src/Annotation/ValueAspect.php b/src/config/src/Annotation/ValueAspect.php index 67d028700..b9b8988f0 100644 --- a/src/config/src/Annotation/ValueAspect.php +++ b/src/config/src/Annotation/ValueAspect.php @@ -11,7 +11,6 @@ declare(strict_types=1); */ namespace Hyperf\Config\Annotation; -use Hyperf\Config\Annotation\Value; use Hyperf\Di\Aop\AbstractAspect; use Hyperf\Di\Aop\ProceedingJoinPoint; diff --git a/src/config/src/ConfigFactory.php b/src/config/src/ConfigFactory.php index 2c57d1c76..49924db73 100644 --- a/src/config/src/ConfigFactory.php +++ b/src/config/src/ConfigFactory.php @@ -11,9 +11,6 @@ declare(strict_types=1); */ namespace Hyperf\Config; -use Dotenv\Dotenv; -use Dotenv\Repository\Adapter; -use Dotenv\Repository\RepositoryBuilder; use Psr\Container\ContainerInterface; use Symfony\Component\Finder\Finder; @@ -21,11 +18,6 @@ class ConfigFactory { public function __invoke(ContainerInterface $container) { - // Load env before config. - if (file_exists(BASE_PATH . '/.env')) { - $this->loadDotenv(); - } - $configPath = BASE_PATH . '/config/'; $config = $this->readConfig($configPath . 'config.php'); $serverConfig = $this->readConfig($configPath . 'server.php'); @@ -34,21 +26,6 @@ class ConfigFactory return new Config($merged); } - private function loadDotenv(): void - { - $repository = RepositoryBuilder::create() - ->withReaders([ - new Adapter\PutenvAdapter(), - ]) - ->withWriters([ - new Adapter\PutenvAdapter(), - ]) - ->immutable() - ->make(); - - Dotenv::create($repository, [BASE_PATH])->load(); - } - private function readConfig(string $configPath): array { $config = []; diff --git a/src/di/src/Annotation/ScanConfig.php b/src/di/src/Annotation/ScanConfig.php index 9a507b69a..db7c5cef3 100644 --- a/src/di/src/Annotation/ScanConfig.php +++ b/src/di/src/Annotation/ScanConfig.php @@ -15,6 +15,11 @@ use Hyperf\Config\ProviderConfig; final class ScanConfig { + /** + * @var string + */ + private $appEnv; + /** * @var string */ @@ -58,6 +63,7 @@ final class ScanConfig private static $instance; public function __construct( + string $appEnv, string $configDir, array $paths = [], array $dependencies = [], @@ -66,6 +72,7 @@ final class ScanConfig array $collectors = [], array $classMap = [] ) { + $this->appEnv = $appEnv; $this->configDir = $configDir; $this->paths = $paths; $this->dependencies = $dependencies; @@ -110,15 +117,23 @@ final class ScanConfig return $this->classMap; } - public static function instance(): self + public function getAppEnv(): string + { + return $this->appEnv; + } + + public static function instance(string $configDir): self { if (self::$instance) { return self::$instance; } - [$config, $serverDependencies] = static::initConfigByFile($configDir = BASE_PATH . '/config'); + $configDir = rtrim($configDir, '/'); + + [$config, $serverDependencies, $appEnv] = static::initConfigByFile($configDir); return self::$instance = new self( + $appEnv, $configDir, $config['paths'] ?? [], $serverDependencies ?? [], @@ -154,11 +169,12 @@ final class ScanConfig // Load the config/config.php and merge the config if (file_exists($configDir . '/config.php')) { $configContent = include $configDir . '/config.php'; + $appEnv = $configContent['app_env'] ?? 'dev'; if (isset($configContent['annotations'])) { $config = static::allocateConfigValue($configContent['annotations'], $config); } } - return [$config, $serverDependencies]; + return [$config, $serverDependencies, $appEnv]; } private static function allocateConfigValue(array $content, array $config): array diff --git a/src/di/src/Annotation/Scanner.php b/src/di/src/Annotation/Scanner.php index 015381e25..ce4c8682c 100644 --- a/src/di/src/Annotation/Scanner.php +++ b/src/di/src/Annotation/Scanner.php @@ -113,6 +113,10 @@ class Scanner $annotationReader = new AnnotationReader(); $lastCacheModified = $this->deserializeCachedCollectors($collectors); + // TODO: The online mode won't init BetterReflectionManager when has cache. + if ($lastCacheModified > 0 && $this->scanConfig->getAppEnv() === 'prod') { + return []; + } $paths = $this->normalizeDir($paths); diff --git a/src/di/src/Aop/ProxyManager.php b/src/di/src/Aop/ProxyManager.php index 53911537a..9bff1be2b 100644 --- a/src/di/src/Aop/ProxyManager.php +++ b/src/di/src/Aop/ProxyManager.php @@ -13,18 +13,16 @@ namespace Hyperf\Di\Aop; use Hyperf\Di\Annotation\AnnotationCollector; use Hyperf\Di\Annotation\AspectCollector; -use Hyperf\Di\BetterReflectionManager; use Hyperf\Utils\Filesystem\Filesystem; -use Roave\BetterReflection\Reflection\ReflectionClass; class ProxyManager { /** - * The map to collect the class names which has been handled. + * The map to collect the classes whith paths. * * @var array */ - protected $classNameMap = []; + protected $classMap = []; /** * The classes which be rewrited by proxy. @@ -46,15 +44,13 @@ class ProxyManager protected $filesystem; public function __construct( - array $reflectionClassMap = [], array $composerLoaderClassMap = [], string $proxyDir = '' ) { + $this->classMap = $composerLoaderClassMap; $this->proxyDir = $proxyDir; $this->filesystem = new Filesystem(); - $reflectionClassMap && $reflectionClassProxies = $this->generateProxyFiles($this->initProxiesByReflectionClassMap($reflectionClassMap)); - $composerLoaderClassMap && $composerLoaderProxies = $this->generateProxyFiles($this->initProxiesByComposerClassMap($composerLoaderClassMap)); - $this->proxies = array_merge($reflectionClassProxies, $composerLoaderProxies); + $this->proxies = $this->generateProxyFiles($this->initProxiesByReflectionClassMap($composerLoaderClassMap)); } public function getProxies(): array @@ -67,16 +63,6 @@ class ProxyManager return $this->proxyDir; } - public function getClassNameMap(): array - { - return $this->classNameMap; - } - - public function isClassHandled(string $className): bool - { - return in_array($className, $this->getClassNameMap()); - } - protected function generateProxyFiles(array $proxies = []): array { $proxyFiles = []; @@ -114,8 +100,8 @@ class ProxyManager { $proxyFilePath = $proxyFilePath ?? $this->getProxyFilePath($className); $time = $this->filesystem->lastModified($proxyFilePath); - $origin = BetterReflectionManager::reflectClass($className); - if ($time > $this->filesystem->lastModified($origin->getFileName())) { + $origin = $this->classMap[$className]; + if ($time > $this->filesystem->lastModified($origin)) { return false; } @@ -145,9 +131,6 @@ class ProxyManager return false; } - /** - * @param ReflectionClass[] $reflectionClassMap - */ protected function initProxiesByReflectionClassMap(array $reflectionClassMap = []): array { // According to the data of AspectCollector to parse all the classes that need proxy. @@ -158,18 +141,17 @@ class ProxyManager $classesAspects = AspectCollector::get('classes', []); foreach ($classesAspects as $aspect => $rules) { foreach ($rules as $rule) { - foreach ($reflectionClassMap as $class) { - if (! $this->isMatch($rule, $class->getName())) { + foreach ($reflectionClassMap as $class => $path) { + if (! $this->isMatch($rule, $class)) { continue; } - $proxies[$class->getName()][] = $aspect; + $proxies[$class][] = $aspect; } } } - foreach ($reflectionClassMap as $class) { - $className = $class->getName(); - $this->classNameMap[] = $className; + foreach ($reflectionClassMap as $class => $path) { + $className = $class; // Aggregate the class annotations $classAnnotations = $this->retrieveAnnotations($className . '._c'); // Aggregate all methods annotations @@ -203,7 +185,6 @@ class ProxyManager if ($classAspects) { foreach ($classMap as $className => $file) { $match = []; - $this->classNameMap[] = $className; foreach ($classAspects as $aspect => $rules) { foreach ($rules as $rule) { if ($this->isMatch($rule, $className)) { diff --git a/src/di/src/ClassLoader.php b/src/di/src/ClassLoader.php index 948084759..90c213d89 100644 --- a/src/di/src/ClassLoader.php +++ b/src/di/src/ClassLoader.php @@ -13,6 +13,9 @@ namespace Hyperf\Di; use Composer\Autoload\ClassLoader as ComposerClassLoader; use Doctrine\Common\Annotations\AnnotationRegistry; +use Dotenv\Dotenv; +use Dotenv\Repository\Adapter; +use Dotenv\Repository\RepositoryBuilder; use Hyperf\Di\Annotation\ScanConfig; use Hyperf\Di\Annotation\Scanner; use Hyperf\Di\Aop\ProxyManager; @@ -37,16 +40,19 @@ class ClassLoader public function __construct(ComposerClassLoader $classLoader, string $proxyFileDir, string $configDir) { $this->setComposerClassLoader($classLoader); - $start = microtime(true); + if (file_exists(BASE_PATH . '/.env')) { + $this->loadDotenv(); + } + // Scan by ScanConfig to generate the reflection class map - $scanner = new Scanner($this, $config = ScanConfig::instance()); + $scanner = new Scanner($this, $config = ScanConfig::instance($configDir)); $classLoader->addClassMap($config->getClassMap()); timepoint(); - $reflectionClassMap = $scanner->scan(); + $scanner->scan(); timepoint('Scan'); // Get the class map of Composer loader $composerLoaderClassMap = $this->getComposerClassLoader()->getClassMap(); - $proxyManager = new ProxyManager($reflectionClassMap, $composerLoaderClassMap, $proxyFileDir); + $proxyManager = new ProxyManager($composerLoaderClassMap, $proxyFileDir); timepoint('InitProxyManager'); $this->proxies = $proxyManager->getProxies(); } @@ -122,4 +128,19 @@ class ClassLoader return is_string($file) ? $file : null; } + + private function loadDotenv(): void + { + $repository = RepositoryBuilder::create() + ->withReaders([ + new Adapter\PutenvAdapter(), + ]) + ->withWriters([ + new Adapter\PutenvAdapter(), + ]) + ->immutable() + ->make(); + + Dotenv::create($repository, [BASE_PATH])->load(); + } }