小白兔晒黑了

导航

 

1反射原理的梳理

1.1 BeanFactory属性注解

seckill\pro\core\BeanFactory.php

    private static function handlerPropAnno(&$instance,\ReflectionClass $refClass,AnnotationReader $reader)
    {
       //读取反射对象的属性
        $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);
            }
        }
    }

其中

第一个参数


//读取反射对象的属性
$props = $refClass->getProperties();
 

第二个参数

$instance = self::$container->get($refClass->getName())

第三个参数

//$prop必须是反射对象属性
$propAnnos = $reader->getPropertyAnnotations($prop);

DB类自身

1.2 handler

seckill\pro\core\annotationhandlers\DBHandler.php

return [
    /**
     * @prop
     * object(ReflectionProperty)#48 (2) {
    ["name"]=>
    string(2) "db"
    ["class"]=>
    string(30) "App\controllers\UserController"
    }
 
     * @instance
     * object(App\controllers\UserController)#52 (2) {
    ["db":"App\controllers\UserController":private]=>
    NULL
    ["version"]=>
    string(3) "1.0"
    }
 
     * @self
     * object(Core\annotations\DB)#55 (1) {
    ["source"]=>
    string(6) "docker"
    }
     */
  DB::class=>function(\ReflectionProperty $prop,$instance,$self) {
      $mydbBean = BeanFactory::getBean(MyDB::class);   //从新获取一个对象
      $mydbBean ->setDbSource($self->source);//annotations/DB 里设置的数据源
      $prop->setAccessible(true);   //
      $prop->setValue($instance,$mydbBean);
      return $instance;
  }
];

第一个参数\ReflectionProperty $prop $prop

来源于 \controllers\UserController.php

第二次参数 $instance

本来是指\controllers\UserController的实例

object(App\controllers\UserController)#52 (2) {
  ["db":"App\controllers\UserController":private]=>
  NULL
  ["version"]=>
  string(3) "1.0"
}

 

经过 $prop->setValue($instance,$mydbBean);后

变成

object(App\controllers\UserController)#52 (2) {
  ["db":"App\controllers\UserController":private]=>
  object(Core\init\MyDB)#37 (2) {
    ["lvDB"]=>
    object(Illuminate\Database\Capsule\Manager)#38 (2) {
      ["manager":protected]=>
      object(Illuminate\Database\DatabaseManager)#45 (6) {
        ["app":protected]=>
        object(Illuminate\Container\Container)#42 (19) {
          ["resolved":protected]=>
          array(0) {
          }
          ["bindings":protected]=>
          array(0) {
          }
          ["methodBindings":protected]=>
          array(0) {
          }
          ["instances":protected]=>
          array(1) {
            ["config"]=>
            object(Illuminate\Support\Fluent)#43 (1) {
              ["attributes":protected]=>
              array(3) {
                ["database.fetch"]=>
                int(5)
                ["database.default"]=>
                string(7) "default"
                ["database.connections"]=>
                array(2) {
                  ["default"]=>
                  array(9) {
                    ["driver"]=>
                    string(5) "mysql"
                    ["host"]=>
                    string(12) "10.10.10.114"
                    ["port"]=>
                    string(4) "3306"
                    ["database"]=>
                    string(4) "test"
                    ["username"]=>
                    string(3) "ttt"
                    ["password"]=>
                    string(6) "123456"
                    ["charset"]=>
                    string(7) "utf8mb4"
                    ["collation"]=>
                    string(18) "utf8mb4_general_ci"
                    ["prefix"]=>
                    string(0) ""
                  }
                  ["docker"]=>
                  array(9) {
                    ["driver"]=>
                    string(5) "mysql"
                    ["host"]=>
                    string(12) "10.10.10.234"
                    ["port"]=>
                    string(5) "12345"
                    ["database"]=>
                    string(7) "seckill"
                    ["username"]=>
                    string(4) "root"
                    ["password"]=>
                    string(6) "123456"
                    ["charset"]=>
                    string(7) "utf8mb4"
                    ["collation"]=>
                    string(18) "utf8mb4_general_ci"
                    ["prefix"]=>
                    string(0) ""
                  }
                }
              }
            }
          }
          ["scopedInstances":protected]=>
          array(0) {
          }
          ["aliases":protected]=>
          array(0) {
          }
          ["abstractAliases":protected]=>
          array(0) {
          }
          ["extenders":protected]=>
          array(0) {
          }
          ["tags":protected]=>
          array(0) {
          }
          ["buildStack":protected]=>
          array(0) {
          }
          ["with":protected]=>
          array(0) {
          }
          ["contextual"]=>
          array(0) {
          }
          ["reboundCallbacks":protected]=>
          array(0) {
          }
          ["globalBeforeResolvingCallbacks":protected]=>
          array(0) {
          }
          ["globalResolvingCallbacks":protected]=>
          array(0) {
          }
          ["globalAfterResolvingCallbacks":protected]=>
          array(0) {
          }
          ["beforeResolvingCallbacks":protected]=>
          array(0) {
          }
          ["resolvingCallbacks":protected]=>
          array(0) {
          }
          ["afterResolvingCallbacks":protected]=>
          array(0) {
          }
        }
        ["factory":protected]=>
        object(Illuminate\Database\Connectors\ConnectionFactory)#44 (1) {
          ["container":protected]=>
          object(Illuminate\Container\Container)#42 (19) {
            ["resolved":protected]=>
            array(0) {
            }
            ["bindings":protected]=>
            array(0) {
            }
            ["methodBindings":protected]=>
            array(0) {
            }
            ["instances":protected]=>
            array(1) {
              ["config"]=>
              object(Illuminate\Support\Fluent)#43 (1) {
                ["attributes":protected]=>
                array(3) {
                  ["database.fetch"]=>
                  int(5)
                  ["database.default"]=>
                  string(7) "default"
                  ["database.connections"]=>
                  array(2) {
                    ["default"]=>
                    array(9) {
                      ["driver"]=>
                      string(5) "mysql"
                      ["host"]=>
                      string(12) "10.10.10.114"
                      ["port"]=>
                      string(4) "3306"
                      ["database"]=>
                      string(4) "test"
                      ["username"]=>
                      string(3) "ttt"
                      ["password"]=>
                      string(6) "123456"
                      ["charset"]=>
                      string(7) "utf8mb4"
                      ["collation"]=>
                      string(18) "utf8mb4_general_ci"
                      ["prefix"]=>
                      string(0) ""
                    }
                    ["docker"]=>
                    array(9) {
                      ["driver"]=>
                      string(5) "mysql"
                      ["host"]=>
                      string(12) "10.10.10.234"
                      ["port"]=>
                      string(5) "12345"
                      ["database"]=>
                      string(7) "seckill"
                      ["username"]=>
                      string(4) "root"
                      ["password"]=>
                      string(6) "123456"
                      ["charset"]=>
                      string(7) "utf8mb4"
                      ["collation"]=>
                      string(18) "utf8mb4_general_ci"
                      ["prefix"]=>
                      string(0) ""
                    }
                  }
                }
              }
            }
            ["scopedInstances":protected]=>
            array(0) {
            }
            ["aliases":protected]=>
            array(0) {
            }
            ["abstractAliases":protected]=>
            array(0) {
            }
            ["extenders":protected]=>
            array(0) {
            }
            ["tags":protected]=>
            array(0) {
            }
            ["buildStack":protected]=>
            array(0) {
            }
            ["with":protected]=>
            array(0) {
            }
            ["contextual"]=>
            array(0) {
            }
            ["reboundCallbacks":protected]=>
            array(0) {
            }
            ["globalBeforeResolvingCallbacks":protected]=>
            array(0) {
            }
            ["globalResolvingCallbacks":protected]=>
            array(0) {
            }
            ["globalAfterResolvingCallbacks":protected]=>
            array(0) {
            }
            ["beforeResolvingCallbacks":protected]=>
            array(0) {
            }
            ["resolvingCallbacks":protected]=>
            array(0) {
            }
            ["afterResolvingCallbacks":protected]=>
            array(0) {
            }
          }
        }
        ["connections":protected]=>
        array(0) {
        }
        ["extensions":protected]=>
        array(0) {
        }
        ["reconnector":protected]=>
        object(Closure)#46 (2) {
          ["this"]=>
          *RECURSION*
          ["parameter"]=>
          array(1) {
            ["$connection"]=>
            string(10) "<required>"
          }
        }
        ["doctrineTypes":protected]=>
        array(0) {
        }
      }
      ["container":protected]=>
      object(Illuminate\Container\Container)#42 (19) {
        ["resolved":protected]=>
        array(0) {
        }
        ["bindings":protected]=>
        array(0) {
        }
        ["methodBindings":protected]=>
        array(0) {
        }
        ["instances":protected]=>
        array(1) {
          ["config"]=>
          object(Illuminate\Support\Fluent)#43 (1) {
            ["attributes":protected]=>
            array(3) {
              ["database.fetch"]=>
              int(5)
              ["database.default"]=>
              string(7) "default"
              ["database.connections"]=>
              array(2) {
                ["default"]=>
                array(9) {
                  ["driver"]=>
                  string(5) "mysql"
                  ["host"]=>
                  string(12) "10.10.10.114"
                  ["port"]=>
                  string(4) "3306"
                  ["database"]=>
                  string(4) "test"
                  ["username"]=>
                  string(3) "ttt"
                  ["password"]=>
                  string(6) "123456"
                  ["charset"]=>
                  string(7) "utf8mb4"
                  ["collation"]=>
                  string(18) "utf8mb4_general_ci"
                  ["prefix"]=>
                  string(0) ""
                }
                ["docker"]=>
                array(9) {
                  ["driver"]=>
                  string(5) "mysql"
                  ["host"]=>
                  string(12) "10.10.10.234"
                  ["port"]=>
                  string(5) "12345"
                  ["database"]=>
                  string(7) "seckill"
                  ["username"]=>
                  string(4) "root"
                  ["password"]=>
                  string(6) "123456"
                  ["charset"]=>
                  string(7) "utf8mb4"
                  ["collation"]=>
                  string(18) "utf8mb4_general_ci"
                  ["prefix"]=>
                  string(0) ""
                }
              }
            }
          }
        }
        ["scopedInstances":protected]=>
        array(0) {
        }
        ["aliases":protected]=>
        array(0) {
        }
        ["abstractAliases":protected]=>
        array(0) {
        }
        ["extenders":protected]=>
        array(0) {
        }
        ["tags":protected]=>
        array(0) {
        }
        ["buildStack":protected]=>
        array(0) {
        }
        ["with":protected]=>
        array(0) {
        }
        ["contextual"]=>
        array(0) {
        }
        ["reboundCallbacks":protected]=>
        array(0) {
        }
        ["globalBeforeResolvingCallbacks":protected]=>
        array(0) {
        }
        ["globalResolvingCallbacks":protected]=>
        array(0) {
        }
        ["globalAfterResolvingCallbacks":protected]=>
        array(0) {
        }
        ["beforeResolvingCallbacks":protected]=>
        array(0) {
        }
        ["resolvingCallbacks":protected]=>
        array(0) {
        }
        ["afterResolvingCallbacks":protected]=>
        array(0) {
        }
      }
    }
    ["dbSource":"Core\init\MyDB":private]=>
    string(6) "docker"
  }
  ["version"]=>
  string(3) "1.0"
}
View Code

 

 

第三个参数 $self

seckill\pro\core\annotations\DB.php的实例

2 我现在的注解类型

 

2.1 @Bean 实例化后加载在IOC容器中

//Spring的@Bean注解用于告诉方法,产生一个Bean对象,然后这个Bean对象交给Spring管理。产生这个Bean对象的方法Spring只会调用一次,随后这个Spring将会将这个Bean对象放在自己的IOC容器中;

/**
 * @Bean
 * @method \Illuminate\Database\Query\Builder table(string  $table,string|null  $as=null,string|null  $connection=null)
 * @method \Illuminate\Database\Query\Builder connection(string|null  $connection=null)
 */
class MyDB

2.2 @DB 数据库资源注解

/**
     * @DB
     * @var MyDB
     */
    private $db;

2.3 @Model 数据模型注解(尚未完成)

2.4 @RequestMapping 路由注解

/**
     * @RequestMapping(value="/test")
     */
    public function test(Response $response )

 

2.5  @Value 属性注解

  /**
     * @Value(name="version")
     * @var string
     */
    public $version = '1.0';

3 多数据源的切换

3.1 使用方法

seckill\pro\app\controllers\UserController.php

 /**
     * @DB(source ="default")
     * @var MyDB
     */
    private $db1;
    
    /**
     * @DB(source ="docker")
     * @var MyDB
     */
    private $db2;
    
    /**
     * @Value(name="version")
     * @var string
     */

3.2 实现

seckill\pro\core\annotationhandlers\DBHandler.php

  DB::class=>function(\ReflectionProperty $prop,$instance,$self) {
      $mydbBean = BeanFactory::getBean(MyDB::class);   //获取IOC容器的对象
      $mydbBean ->setDbSource($self->source);
      if ($self->sourc!=='default'){
          $newBeanName = MyDB::class."_".$self->source;
          $newBean =  BeanFactory::getBean($newBeanName);
          if(!$newBean){
              $newBean = clone  $mydbBean ;
              $newBean ->setDbSource($self->source);//默认为annotations/DB 里设置的数据源
              BeanFactory::setBean($newBeanName,$newBean);
          }
          $mydbBean =   $newBean;
      }
      $prop->setAccessible(true);   //
      //ReflectionProperty::setValue( object $object , mixed $value )
      //$instance 如果该属性是非静态的,则必须提供一个对象以更改该属性。 如果属性是静态的,则忽略此参数,仅需要提供值。
      //$mydbBean 新的属性值
      //把lvDB装载到UserController的实例里
      $prop->setValue($instance,$mydbBean);
      return $instance;
  }

seckill\pro\core\BeanFactory.php

  public static function setBean($name,$value)
    {
        return self::$container->set($name,$value);
    }

4 完整代码

https://github.com/guainttt/seckill/commit/b1db22b9209473eeaa4d289643df1b26db79f851

 

posted on 2022-09-27 01:33  小白兔晒黑了  阅读(18)  评论(0编辑  收藏  举报