swoole-framwork/core/BeanFactory.php

163 lines
5.6 KiB
PHP
Raw Permalink Normal View History

2024-05-20 11:51:07 +08:00
<?php
namespace Core;
use DI\ContainerBuilder;
use Doctrine\Common\Annotations\AnnotationReader;
2024-05-21 14:33:56 +08:00
use Doctrine\Common\Annotations\AnnotationRegistry;
2024-05-20 11:51:07 +08:00
class BeanFactory
{
//配置文件
private static $env = [];
//IOC容器
private static $container;
private static $handlers = [];
//初始化函数
2024-06-26 17:13:45 +08:00
public static function init($bool = false)
2024-05-20 11:51:07 +08:00
{
self::$env = parse_ini_file(ROOT_PATH . "/.env");
//初始容器Builder
$builder = new ContainerBuilder();
//启用注释 主要是用它的Inject注释
2024-05-31 14:57:01 +08:00
$builder->useAttributes(false);
2024-05-20 11:51:07 +08:00
//容器初始化
self::$container = $builder->build();
$handlers = glob(ROOT_PATH . "/core/annotationhandlers/*.php");
foreach ($handlers as $handler) {
self::$handlers = array_merge(self::$handlers, require_once($handler));
}
2024-05-21 14:33:56 +08:00
2024-05-20 11:51:07 +08:00
//扫描(重点)
$scans = [
//必须扫描的文件夹
ROOT_PATH . "/core/init" => "Core\\",
//用户配置的扫描路径
self::_getEnv("scan_dir", ROOT_PATH . "/app") => self::_getEnv("scan_root_namespace", "APP\\")
];
//$scanDir = self::_getEnv("scan_dir",ROOT_PATH."/app");
//$scanRootNamespace = self::_getEnv("scan_root_namespace","APP\\");
foreach ($scans as $scanDir => $scanRootNamespace) {
self::ScanBeans($scanDir, $scanRootNamespace);
}
//self::ScanBeans();
}
private static function getAllBeanFiles($dir)
{
$ret = [];
$files = glob($dir . "/*");
foreach ($files as $file) {
if (is_dir($file)) {
//递归合并,防止数组变成嵌套数组
$ret = array_merge($ret, self::getAllBeanFiles($file));
} elseif (pathinfo($file)["extension"] == "php") {
$ret[] = $file;
}
}
return $ret;
}
//获取env文件的配置内容
private static function _getEnv(string $key, string $default = '')
{
if (isset(self::$env[$key]))
return self::$env[$key];
return $default;
}
public static function ScanBeans($scanDir, $scanRootNamespace)
{
//$files = glob($scanDir."/*.php");
$files = self::getAllBeanFiles($scanDir);
foreach ($files as $file) {
require_once $file;
}
//注释类对象
$reader = new AnnotationReader();
//get_declared_classes返回由已定义类的名字所组成的数组
foreach (get_declared_classes() as $class) {
if (strstr($class, $scanRootNamespace)) {
$refClass = new \ReflectionClass($class);
2024-05-21 14:33:56 +08:00
//AnnotationRegistry::loadAnnotationClass($class);
2024-05-20 11:51:07 +08:00
//获取所有类的注释
$classAnnos = $reader->getClassAnnotations($refClass);
2024-05-31 14:57:01 +08:00
if ($refClass->getName() == 'Core\server\HttpServer') {
continue;
}
2024-05-20 11:51:07 +08:00
$instance = self::$container->get($refClass->getName());
foreach ($classAnnos as $classAnno) {
//根据注释的类型获取对应处理方法
$hander = self::$handlers[get_class($classAnno)];
//$hander($instance, self::$container);
self::handlerPropAnno($instance,$refClass,$reader);
//处理方法注解
self::handlerMethodAnno($instance,$refClass,$reader);
//处理类注解
$hander($instance,self::$container,$classAnno);
}
//self::handlerMethodAnno($instance, $refClass, $reader);
}
}
}
public static function getBean($name)
{
try {
return self::$container->get($name);
} catch (\Exception $exception) {
return false;//没有找到直接返回false
}
}
public static function setBean($name, $value)
{
return self::$container->set($name, $value);
}
private static function handlerPropAnno(&$instance, \ReflectionClass $refClass, AnnotationReader $reader)
{
2024-06-26 17:13:45 +08:00
//var_dump($refClass->getName());
2024-05-20 11:51:07 +08:00
//读取反射对象的属性
$props = $refClass->getProperties();
foreach ($props as $prop) {
//$prop必须是反射对象属性
$propAnnos = $reader->getPropertyAnnotations($prop);
foreach ($propAnnos as $propAnno) {
//返回对象实例 obj 所属类的名字。如果 obj 不是一个对象则返回 FALSE
$handler = self::$handlers[get_class($propAnno)];
$handler($prop, $instance, $propAnno);
}
}
}
/**
* 处理方法注解
* @param $instance
* @param \ReflectionClass $refClass
* @param \Doctrine\Common\Annotations\AnnotationReader $reader
*/
private static function handlerMethodAnno(&$instance, \ReflectionClass $refClass, AnnotationReader $reader)
{
//读取反射对象的属性
$methods = $refClass->getMethods();//取出所有的方法
foreach ($methods as $method) {
//$prop必须是反射对象属性
$methodAnnos = $reader->getMethodAnnotations($method);
foreach ($methodAnnos as $methodAnno) {
//返回对象实例 obj 所属类的名字。如果 obj 不是一个对象则返回 FALSE
$handler = self::$handlers[get_class($methodAnno)];
$handler($method, $instance, $methodAnno);
}
}
}
}