ioc与aop理解与实现

一、ioc理解:

  IoC,(Inverse of Control)控制反转,其包含两个内容:其一是控制,其二是反转。在程序中,被调用类的选择控制权从调用它的类中移除,转交给第三方裁决。这个第三方指的就是Spring的容器。IoC另解,依赖注入(Dependency Injection),调用类对被调用类的依赖关系由第三方注入,以移除调用类对被调用类的引用。

二、aop理解:

  aop,面向切面编程(也叫面向方面):Aspect Oriented Programming(AOP),是目前软件开发中的一个热点。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。  AOP是OOP的延续,是(Aspect Oriented Programming)的缩写,意思是面向切面(方面)编程。主要的功能可用到:日志记录,性能统计,安全控制,事务处理,异常处理等等。   主要的意图是:将日志记录,性能统计,安全控制,事务处理,异常处理等代码从业务逻辑代码中划分出来,通过对这些行为的分离,我们希望可以将它们独立到非指导业务逻辑的方法中,进而改 变这些行为的时候不影响业务逻辑的代码。

 

三、php代码实现ioc与aop思想:

1、Ioc容器

<?php
/**
 * 工具类,使用该类来实现自动依赖注入
 * 使用php的反射函数,创建了一个容器类,
 * 使用该类来实现其他类的依赖注入功能。
 * 依赖注入分为两种:
 * 一种是构造函数的依赖注入,
 * 一种是方法的依赖注入。
 * User: Administrator
 * Date: 2018/5/28
 * Time: 15:15
 */
class Ioc{
    /**
     * 获得类的对象实例
     * @param $className [类名]
     * @return object  [指定类实例化]
     * @throws ReflectionException
     */
    public static function getInstance($className){
        $paramArr = self::getMethodParams($className);
        return (new ReflectionClass($className))->newInstanceArgs($paramArr);
    }

    /**
     * 执行类的方法
     * @param $className [类名]
     * @param $methodName [方法名称]
     * @param array $params [额外的参数]
     * @return mixed
     * @throws ReflectionException
     */
    public static function make($className,$methodName,$params = []){
        // 获取类的实例
        $instance = self::getInstance($className);

        // 获取该方法所需要依赖注入的参数
        $paramArr = self::getMethodParams($className, $methodName);

        return $instance->{$methodName}(array_merge($paramArr, $params));
    }

    /**获得类的方法参数,只获得有类型的参数
     * @param $className
     * @param string $methodsName
     * @return array
     * @throws ReflectionException
     */
    protected static function getMethodParams($className, $methodsName = '__construct') {

        // 通过反射获得该类
        $class = new ReflectionClass($className);
        $paramArr = []; // 记录参数,和参数类型

        // 判断该类是否有构造函数
        if ($class->hasMethod($methodsName)) {
            // 获得构造函数
            $construct = $class->getMethod($methodsName);

            // 判断构造函数是否有参数
            $params = $construct->getParameters();

            if (count($params) > 0) {

                // 判断参数类型
                foreach ($params as $key => $param) {

                    if ($paramClass = $param->getClass()) {

                        // 获得参数类型名称
                        $paramClassName = $paramClass->getName();

                        // 获得参数类型
                        $args = self::getMethodParams($paramClassName);
                        $paramArr[] = (new ReflectionClass($paramClass->getName()))->newInstanceArgs($args);
                    }
                }
            }
        }

        return $paramArr;
    }
}

2、分别创建A、B、C三个类

<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2018/5/28
 * Time: 15:30
 */
class A{
    protected $cobj;

    /**
     * 用于测试多级依赖注入 B依赖A,A依赖C
     * @param C $c
     */
    public function __construct(C $c)
    {
        $this->cobj = $c;
    }

    public function aa(){
        echo 'this is A->aa';
    }

    public function aac(){
        $this->cobj->cc();
    }
}
<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2018/5/28
 * Time: 15:32
 */
class B{
    protected $aobj;

    /**
     * 测试构造函数依赖注入
     * @param A $a
     */
    public function __construct(A $a)
    {
        $this->aobj = $a;
    }

    /**
     * 测试构造函数依赖注入
     * @param C $c  依赖注入C
     * @param $b
     */
    public function bb(C $c,$b){
        $c->cc();
        echo "<br/>";
        echo "param:".$b;
    }

    /**
     * 验证依赖注入是否成功
     */
    public function bbb(){
        $this->aobj->aac();
    }
}
<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2018/5/28
 * Time: 15:32
 */
class C{
    public function cc(){
        echo 'this is C->cc';
    }
}

3、测试类

<?php
/**
 * PHP反射机制实现自动依赖注入
 * User: Administrator
 * Date: 2018/5/28
 * Time: 15:52
 */
$bobj = Ioc::getInstance('B');
$bobj->bbb();

//include('Ioc.php');
//自动加载类
function __autoload($class_name)
{
    require_once $class_name.'.php';
}

//析构方法B
function __destruct(){
    echo "最后输出";
}

 

posted @ 2018-08-01 13:49  Mr*wang  阅读(424)  评论(0)    收藏  举报