基於JDK官方實現接口的動態代理對象, 可以在不修改原類中方法的基礎上,對類中方法進行增強.
package com.hr.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 Producer producer = new Producer();
/**
* 動態代理:
* 特點: 字節碼隨用隨創建,隨用隨加載
* 作用: 不修改源碼的基礎上對方法增強
* 分類:
* 基於接口的動態代理
* 基於子類的動態代理
* 基於接口的動態代理:
* 涉及的類:Proxy
* 提供者:JDK
* 創建代理對象:
* Proxy類中的newProxyInstance方法
* newProxyInstance方法的參數:
* ClassLoader:
* 用於加載代理對象字節碼,和被代理對象使用相同的類加載器,代理誰寫誰的類加載器,固定寫法
* Class[]:
* 讓代理對象和被代理對象有相同的方法,固定寫法
* InvocationHandler: 用於提供增強的代碼
* 它是讓我們寫如何代理,我們一般都是寫一個該接口的實現類,通常都是匿名內部類
*
*
*/
IProducer proxyProducer = (IProducer) Proxy.newProxyInstance(producer.getClass().getClassLoader(), producer.getClass().getInterfaces(),
new InvocationHandler() {
/**
* 執行被代理對象的任何接口方法都會經過該方法
* @param proxy 代理對象的引用(一般不用)
* @param method 當前執行方法
* @param args 當前執行方法所需的參數
* @return 和被代理對象有相同的返回值
* @throws Throwable
*/
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//提供增強的代碼
Object returnValue = null;
//1 獲取方法執行的參數
Float money = (Float) args[0];
//2 判斷當前方法是不是 銷售方法
if("saleProduct".equals(method.getName())) {
//執行方法
returnValue = method.invoke(producer, money * 0.8f);
}
return returnValue;
}
});
proxyProducer.saleProduct(10000f);
}
}
github託管地址: https://github.com/2402zmybie/spring03_02proxy