Java-JDK動態代理(AOP)使用及實現原理分析

Java-JDK動態代理(AOP)使用及實現原理分析

第一章:代理的介紹

介紹:咱們須要掌握的程度java

動態代理(理解) 基於反射機制spring

掌握的程度:數組

1.什麼是動態代理?mybatis

2.動態代理可以作什麼?框架

後面咱們在用Spirng和Mybatis的時候,要理解怎麼使用的.ide

1.什麼是代理?

代理,在咱們平常生活之中就有體現,代購,中介,換ip,商家等等.工具

好比有一家美國的大學,能夠對全世界招生.留學中介(代理 )學習

留學中介(代理):幫助這家美國的學校招生,中介是學校的代理中介是代替學校完成招生功能
代理特色代理

  1. 中介和代理他們要作的事情是一致的:招生
  2. 中介是學校代理,學校是目標
  3. 家長-------->中介(學校介紹,辦理入學手續)---------->美國學校
  4. 中介是代理,收取費用

2.爲何要找中介

爲何要找中介?
1.中介是專業的,方便.
2.家長如今不能本身去找學校。家長沒有能力訪問學校.或者美國學校不接收我的來訪code

買東西都是商家賣, 商家是某個商品的代理, 你我的買東西,確定不會讓你接觸到廠家的.

第二章:靜態代理

2.1 使用代理模式的做用

  1. 功能加強:在你原有的功能上,增長了額外的功能.新增長的功能,叫作功能加強
  2. 控制訪問:代理類不讓你訪問目標,例如商家不讓用戶訪問廠家

2.2 實現代理的方式

1.靜態代理:

1)代理類是本身手工實現的,本身建立一個java類,表示代理類

2)同時你所要代理的目標

特色:1)實現簡單2)容易理解。
模擬一個用戶購買u盤的行爲。
用戶是客戶端類
商家:代理,代理某個品牌的u盤。
廠家:目標類。
三者的關係:用戶(客戶端)-—-商家(代理)-—-廠家(目標)
商家和廠家都是賣u盤的,他們完成的功能是一致的,都是賣u盤。

實現步驟:

實現步驟
1.建立一個接口,定義賣u盤的方法,表示你的廠家和商家作的事情
2.建立廠家類,實現1步驟的接口
3.建立商家,就是代理,也須要實現1步驟中的接口
4.建立客戶端類,調用商家的方法買一個u盤

2.3 具體實現

實現步驟
1.建立一個接口,定義賣u盤的方法,表示你的廠家和商家作的事情

package com.rango.service;
public interface usbSell {
    /**
     * 定義一個方法 參數 amount:表示一次購買的數量,暫時不用
     * 返回值表示一個u盤的價格
     * @param amount
     * @return
     */
    float sell(int amount);
}

2.建立廠家類,實現1步驟的接口

package com.rango.factory;

import com.rango.service.usbSell;
//目標類:金士頓廠家,不接受用戶的單獨購買
public class UsbKingFactory implements usbSell {
    /**
     * 定義一個方法 參數 amount:表示一次購買的數量,暫時不用
     * 返回值表示一個u盤的價格
     *
     * @param amount
     * @return
     */
    @Override
//一個128G的U盤是85元.
//    後期根據amount,能夠實現不一樣的價格,例如10000個,單擊是80,50000個75
    public float sell(int amount) {
        return 85.0f*amount;
    }
}

3.建立商家,就是代理,也須要實現1步驟中的接口

package com.rango.business;

import com.rango.factory.UsbKingFactory;
import com.rango.service.usbSell;


//淘寶是一個商家,代理金士頓U盤的銷售
public class TaoBao implements usbSell {
//      聲明 商家代理的廠家具體是誰
    private UsbKingFactory factory =new UsbKingFactory();

    @Override
//    實現銷售U盤功能
    public float sell(int amount) {
//        向廠家發送訂單,告訴廠家,我買了U盤,廠家發貨
//        發送給工廠,我須要的訂單,返回報價
        float price = factory.sell(amount);
//        商家須要加價也就是代理要增長價格
        price = price + 25;
//在目標類的方法調用後,你作的其餘功能,都是加強的意思
        System.out.println("淘寶再給你返回一個優惠券,或者紅包");
//        增長的價格
        return price;
    }
}

4.建立客戶端類,調用商家的方法買一個u盤

import com.rango.business.TaoBao;

public class shopMain {
    public static void main(String[] args){
//             建立代理的商家淘寶對象
        TaoBao taoBao = new TaoBao();
//        我只向淘寶買一件產品,獲得報價
        float price = taoBao.sell(2);
        System.out.println("購買一件產品.淘寶的報價爲: "+price);
    }
}

因此咱們再次總結代理類完成的功能:

  1. 目標類中方法的調用
  2. 功能加強

所屬咱們只有一個代理商,咱們實際上能夠寫多個代理商,

2.4 靜態代理的優缺點

咱們再次總結一下靜態代理的優缺點

優勢:

  1. 實現簡單
  2. 容易簡單

肯定:當你的項目中,目標類的代理類不少的時候,有一下的缺點

  1. 當目標類增長了,代理類可能也須要成倍的增長
  2. 當你的接口中功能在增長了,或者修改了,會影響衆多的實現類,廠家類,代理都須要修改,影響比較多.

因此咱們繼續學習動態代理

第三章 動態代理

本章,咱們所掌握的是

1)什麼是動態代理?

​ 使用jdk的反射機制,建立對象的能力,建立的是代理類的的對象.而不用咱們建立類文件,不用寫java文件, 什麼叫動態?在程序執行時,調用jdk提供的方法才能建立代理類的對象

2)知道動態代理能作什麼?

2.1 靜態代理和動態代理模式的對比

在靜態代理中目標不少的時候,能夠使用動態代理,避免靜態代理的缺點

在靜態代理中目標類不少時候,能夠使用動態代理,避免靜態代理的缺點。
動態代理中目標類即便不少,

  1. 代理類數量能夠不多,

  2. 當你修改了接口中的方法時,不會影響代理類。

動態代理:在程序執行過程當中,使用jdk的反射機制,建立代理類對象,並動態的指定要代理目標類。
換句話說:動態代理是一種建立java象的能力,讓你不用建立 TaoBao類就能建立代理類對象,除去了中間商

在java中,要想建立對象

  1. 建立類文件,java 文件編譯爲class
  2. 使用構造方法,建立類的對象

2.1 動態代理的介紹

  1. 動態代理是指代理類對象在程序運行時由JVM根據反射機制動態生成的。動態代理不須要定義代理類的,java源文件。
  2. 動態代理其實就是jdk運行期間,動態建立class字節碼並加載到JVM。
  3. 動態代理的實現方式經常使用的有兩種:使用JDK代理,與經過CGLlB動態代理。

動態代理的實現:

  1. jdk動態代理(理解):使用java反射包中的類和接口實現動態代理的功能,反射包java.lang.reflect,裏面有三個類:InvocationHandler,Method,Proxy
  2. cglib動態代理(瞭解): cglib是第三方的工具庫,建立代理對象
    1. cglib的原理是繼承,cglib經過繼承目標類,建立它的子類,在子類中
      重寫父類中同名的方法,實現功能的修改。
    2. 由於cglib是繼承,重寫方法,因此要求目標類不能是fina1的,方法也不能是final的。cglib的要求目標類比較寬鬆,只要能繼承就能夠了。cglib在不少的框架中使用,
      好比mybatis,spring框架中都有使用。
package Test;

import com.rango.Impl.HelloServiceImpl;
import com.rango.service.HelloService;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class TestApp {
    public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
//        HelloService service = new HelloServiceImpl();
//        service.sayhello("張三");
//        以上是常規方法執行sayhello
//        下面咱們使用反射機制進行建立sayhello方法,核心Method(類中的方法)
        HelloServiceImpl target = new HelloServiceImpl();
//        獲取sayhello名稱對應的Method類對象
//         public Method getM   ethod(String name, Class<?>... parameterTypes)
//        加入,該方法的參數有多個該怎麼辦?
//        parameterTypes參數是一個類對象數組,按聲明的順序標識方法的形式參數類型。
        Method method = HelloService.class.getMethod("sayhello", String.class);
//        經過Metho能夠執行sayhello方法的調用
        /*
        *  public Object invoke(Object obj, Object... args)
        *       表示執行方法的調用
        *   參數:
        *       1.Object,表示對象,要執行這個對象的方法
        *       2.Object...args,方法執行時的參數值
        * 返回值:
        *       Object:方法執行後的返回值
        * */
        Object ret = method.invoke(target, "李四");
    }
}

2.2 回顧反射 Method類

Method類的結構圖

  • Class Method
    • java.lang.Object
      • java.lang.reflect.AccessibleObject
        • java.lang.reflect.Executable
          • java.lang.reflect.Method

2.2.1 class.getMethod

Method method = HelloService.class.getMethod("sayhello", String.class,Integer.class);

提出問題?

public Method getMethod(String name, Class<?>... parameterTypes)

加入,該方法的參數有多個該怎麼辦?
parameterTypes參數是一個類對象數組,按聲明的順序標識方法的形式參數類型。

2.2.2 Method.invoke

public Object invoke(Object obj,Object... args)

*  public Object invoke(Object obj, Object... args)
*       表示執行方法的調用
*   參數:
*       1.Object,表示對象,要執行這個對象的方法
*       2.Object...args,方法執行時的參數值
* 返回值:
*       Object:方法執行後的返回值
*

2.3 JDK動態代理

相關文章
相關標籤/搜索