Don't use br to reflect classes in online mode.

This commit is contained in:
李铭昕 2020-05-22 19:29:27 +08:00
parent 30af4172b4
commit 8cf2ae9db0
6 changed files with 59 additions and 61 deletions

View File

@ -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;

View File

@ -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 = [];

View File

@ -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

View File

@ -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);

View File

@ -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)) {

View File

@ -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();
}
}