1.基於jdk動態代理實現方式
/** * 模擬一個消費者 */ 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 */ @Override 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; } }); String result = proxyProducer.saleProduct(10000f); System.out.println(result); } }
/** * 一個生產者 */ public class Producer implements IProducer{ /** * 銷售 * @param money */ public String saleProduct(float money){ System.out.println("銷售產品,並拿到錢:"+money); return money+""; } }
2.1.基於cglib代理實現方式
** * 模擬一個消費者 */ public class Client { public static void main(String[] args) { final Producer producer = new Producer(); /** * 動態代理: * 特點:字節碼隨用隨創建,隨用隨加載 * 作用:不修改源碼的基礎上對方法增強 * 分類: * 基於接口的動態代理 * 基於子類的動態代理 * 基於子類的動態代理: * 涉及的類:Enhancer * 提供者:第三方cglib庫 * 如何創建代理對象: * 使用Enhancer類中的create方法 * 創建代理對象的要求: * 被代理類不能是最終類 * create方法的參數: * Class:字節碼 * 它是用於指定被代理對象的字節碼。 * * Callback:用於提供增強的代碼 * 它是讓我們寫如何代理。我們一般都是些一個該接口的實現類,通常情況下都是匿名內部類,但不是必須的。 * 此接口的實現類都是誰用誰寫。 * 我們一般寫的都是該接口的子接口實現類:MethodInterceptor */ Producer cglibProducer = (Producer)Enhancer.create(producer.getClass(), new MethodInterceptor() { /** * 執行北地阿里對象的任何方法都會經過該方法 * @param proxy * @param method * @param args * 以上三個參數和基於接口的動態代理中invoke方法的參數是一樣的 * @param methodProxy :當前執行方法的代理對象 * @return * @throws Throwable */ @Override public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) 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; } }); cglibProducer.saleProduct(12000f); } }
/** * 一個生產者 */ public class Producer { /** * 銷售 * @param money */ public void saleProduct(float money){ System.out.println("銷售產品,並拿到錢:"+money); } }