IOC,AOP

weixin_47285644發表於2020-12-05

IOC

IOC,也就是控制反轉。 比如: A物件裡面依賴了一個B物件,也就是我們通常說的在A物件裡面實現這個B物件, 也就說說B物件是由A物件控制的。 IOC的意思就是說,將B物件的控制權交給第三方來控制,也就是IOC容器,所以,當物件A執行到需要物件B的時候,IOC容器會主動建立一個物件B注入到物件A需要的地方。

DI 依賴注入

A物件依賴B,我們只需要將B注入A物件就可以了。 IOC是目的,DI是一種手段。 IOC和DI是相輔相成的東西。所謂依賴注入,就是由IOC容器在執行期間,動態地將某種依賴關係注入到物件之中。

IOC的優缺點

第一、軟體系統中由於引入了第三方IOC容器,生成物件的步驟變得有些複雜,本來是兩者之間的事情,又憑空多出一道手續,所以,我們在剛開始使用IOC框架的時候,會感覺系統變得不太直觀。所以,引入了一個全新的框架,就會增加團隊成員學習和認識的培訓成本,並且在以後的執行維護中,還得讓新加入者具備同樣的知識體系。

第二、由於IOC容器生成物件是通過反射方式,在執行效率上有一定的損耗。如果你要追求執行效率的話,就必須對此進行權衡。

第三、具體到IOC框架產品(比如:Spring)來講,需要進行大量的配製工作,比較繁瑣,對於一些小的專案而言,客觀上也可能加大一些工作成本

第四、IOC框架產品本身的成熟度需要進行評估,如果引入一個不成熟的IOC框架產品,那麼會影響到整個專案,所以這也是一個隱性的風險。

OC 的思想最核心的地方在於,資源不由使用資源的雙方管理,而由不使用資源的第三方管理。

    第一,資源集中管理,實現資源的可配置和易管理

    第二,降低了使用資源雙方的依賴程度,也就是我們說的耦合度

AOP

面向切面程式設計,AOP實際上是由OOP演變過來。 比如, 每個介面都需要鑑權邏輯,正常的思路就是在需要鑑權或者打日誌的地方切一刀就可以了,把需要複用的邏輯填進去。這個過程一般就是通過di實現的。

同現實中“代理”一詞的意思相同:比如我要去買保險,要呼叫的關鍵方法只有一個:傳入人民 幣,拿到保單;但這其中還有很多跟我關注的核心方法無關的動作執行,如填寫資料表,稽核資料, 提交證明. . . 與是,我通過一個保險代理人來買保險—通過代理物件執行我需要的呼叫----我就 可專注於自己想要的東東了。
呼叫一個物件的方法時,可通這呼叫這個物件的“代理物件“執行,如果某些方法要日誌記錄 , 事務管理,審計…,就只需修改代理類中的方法,而不必修改物件“原類”中的程式碼。要實現這一功 能,必須先編寫一個通用的代理類,

程式碼實現:

public class DebugVehicleProxy implements InvocationHandler {

    public DebugVehicleProxy(Object obj) {
        this.obj = obj;
    }

    //被代理物件
    private Object obj;

    //得到代理物件
    public static Object getProxy(Object obj) {
        System.out.println("getProxy被呼叫了");
        return java.lang.reflect.Proxy.newProxyInstance(obj.getClass() .getClassLoader(),
                obj.getClass().getInterfaces(),
                new DebugVehicleProxy(obj));
    }


/**
 * 實現InvocationHandler中的方法
 * 被代理類呼叫時,實際上是通過這個方法呼叫的 * @param proxy:被呼叫方法的物件
 * @param method:要呼叫的方法物件
 * @param args:呼叫方法的引數列表
 */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) {
        System.out.println("invoke被呼叫了");
        Object result = null;
        try {
            System.out.println("debug advice begin:" + method.getName());
            result = method.invoke(obj,args);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
        finally {
            System.out.println("debug advice finash:" + method.getName());
        }
        return result;
    }
}


//測試

public class Driver {
    public static void main(String[] args) {
        IVehicle iVehicle = new BMW();
        //代理前執行:
        iVehicle.forward(100);
        //通過代理物件執行
        IVehicle vehicle = (IVehicle) DebugVehicleProxy.getProxy(iVehicle);
        vehicle.forward(200);

    }
}

相關文章