1. 程式人生 > >Spring的AOP 動態代理基礎--java代理物件的程式碼演示

Spring的AOP 動態代理基礎--java代理物件的程式碼演示

必用 的Spring 是以後的程式設計 的生態

Spring–AOP ===預設就是 JDK 的動態代理 -----》
Spring 動態代理的選擇
----spring的通知: 就是增強–
連線點— 就是 方法
切入點----- 要增強的方法
連線點與 切入點 的區別: 實現裡的 SQL語句不同
AOP 程式設計------》 把公用的程式碼抽取 出來—》Spring 執行階段裡
要增強的程式碼----》
AOP 概念: 在 查詢執行期間 不需改變原碼 通過動態代理 增強。。。。。。
AOP------》 面向切片 的 的方式 ? 我們可以 在 執行前 與 執行後 做增強
總共有5種的 :
解決
作用: 就是 動態代理的核心 ====》 不使用 原碼 達到 對已有程式碼的增強
基於xml 配置檔案的
基於spring 的核心
AOP:----預編譯 ---- 執行期 動態代理 可重用性
我們要怎麼給Spring 說明白 的-----》
jdk 動態代理 的 原理是 基於介面的
在不改變原始碼的 時候 增強了
java動態代理的 實現是 :
基於生活的理喻
My---- new impl()----> serviceImpl(原物件)----女朋友
\ /
\ /
\ /
要結婚-談彩禮|(代理)

我們通過程式碼來演示 -----------》proxy實現的 編碼原理

package com.fhw.proxy;
/* 對生產廠家要求的 介面*/
public interface IProducer {

/*
 * 一個生產者: 買東西
 * sale:銷售 Producer:生產者
 * saleProducer
 * */


    /*銷售 與生產*/
    public void saleProducer(float money);

    /**
     *
     * @param money
     */
    public void afterService(float money) ;
}

介面的實現類

package com.fhw.proxy;
/*

  • 一個生產者: 買東西
  • sale:銷售 Producer:生產者
  • saleProducer
  • */

public class Producer implements IProducer {
/銷售 與生產/
public void saleProducer(float money) {
System.out.println(“銷售 產品的錢”+money);
}

/**
 *
 * @param money
 */
public void afterService(float money) {

    System.out.println("銷後服務,的錢"+money);
}

}

proxy 的main測試

package com.fhw.proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/模擬消費者:類;/
public class Client {
public static void main(String[] args) {
//當匿名物件訪問 外部成員的時候 外部成員是最終的 final 的
final Producer producer = new Producer();
/*
* 動態代理 : 特點 : 位元組碼 隨用 隨建立 隨用隨載入
* 作用 : 不修改程式碼 對方法增強
* 分類: 1:基於 介面的
* 2:基於 子類的
* --------------
* 基於介面 的 動態代理 —>提供:JDK 官方
* ------用 proxy 類當中 的
* 需要一個介面 ‘ 來完成動態代理
* newProxyInstance : new代理 例項
* ClassLoader: 類載入: 代理物件 位元組碼
* 代理物件 和 被代理物件使用相同的位元組碼
* (寫的 是 :要代理物件的…getClass().getClassLoader())
* Class[] :位元組碼陣列 用於 代理物件與 被代理 物件 有相同方法
InvocationHandler 呼叫處理: 如何代理 增強的
改介面的實現類 就是匿名類
誰用誰寫
* /
/載入類與載入介面 與實現類/
IProducer proxyProducer = (IProducer)Proxy.newProxyInstance(producer.getClass().getClassLoader()
, producer.getClass().getInterfaces(),
new InvocationHandler() {
/
*
invoke方法 作用:執行被代理 物件 的任何 方法都會 進過該方法
當匿名物件訪問 外部成員的時候 外部成員是最終的 final 的
* @param proxy 代理物件 的引用
* @param method 當前執行方法
* @param args :引數 (當前執行方法)
* @return 和被代理物件 有相同的返回值
* @throws Throwable
/
/
有攔截的功能 : 任何方法都會經過這個方法
/
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//提供增強的 程式碼—>獲取方法執行的引數
Object returnValue=null;
Float money=(Float)args[0] ;//j=就一個index 0 的args
//判斷掛起方法的是不是 銷售
if (“saleProducer”.equals(method.getName())){
returnValue=method.invoke(producer,money*0.8f);//要代理的物件
}
//return method.invoke(producer,
return returnValue;//要代理的物件
}
});
proxyProducer.saleProducer(10000f);
}
}

測試: 控制檯 日誌 的擷取

com.fhw.proxy.Client
銷售 產品的錢8000.0

Process finished with exit code 0