1. 程式人生 > >動態代理知識詳解

動態代理知識詳解

動態代理實現的兩種方式

給動態代理舉個栗子:例如我們平時買膝上型電腦,很多時候都是不從廠家拿貨,而是通過經銷商買電腦。代理模式出現解決了生產廠家的一些問題,那麼這個這個思想在我們程式設計中是怎麼體現的啦???

下面根據具體的案例來解釋

目錄結構

1、基於介面動態代理

該方式的缺點:如果類不實現介面,代理是無法使用

* 動態代理的特點就是位元組碼,隨用隨建立,隨用隨載入
* 作用:在不修改原始碼的基礎上對方法的增強
* 分類:
*      基於介面動態代理
*      基於子類的動態代理
* 基於介面的動態代理
*      涉及類:proxy
*      提供者:jdk官方
* 如何建立動態代理物件
*      使用proxy中的newProxyInstance方法
* 建立代理物件的要求:
*      被代理的物件至少實現一個介面,如果沒有則不能使用
* newProxyInstance方法的引數
* classLoader  用於載入代理物件的位元組碼,寫的是被代理物件的類載入器,和被代理物件使用相同的類載入器(固定寫法)
* Class[]   它是用於代理物件和被代理物件有相同的方法(固定寫法)
* InvocationHandler 用於增強的代理,含義是寫如何代理,我們一般是寫一個該介面的實現類,
* 通常情況下是匿名內部類(匿名內部類訪問外部成員時,需要用final修飾),但是不必須,都是誰用誰寫

案例如下:

介面
package com.cc.proxy;

public interface IProducer {

    public void saleProduct(float money);

    public void afterService(float money);

}
package com.cc.proxy;

/**
 * 一個生產者
 */
public class Producer implements IProducer{
    /**
     * 銷售
     */
    public void saleProduct(float money){
        System.out.println("銷售產品,拿到錢:"+money);
    }

    /**
     * 售後
     */
    public void afterService(float money){
        System.out.println("提供售後服務,並拿到錢"+money);
    }
}

測試方法

package com.cc.proxy;

import org.junit.Test;

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

/**
 * 模擬一個消費者
 * 基於介面的動態代理,如果類不實現介面代理是無法使用
 */
public class Client {
   @Test
    public void test(){
       final Producer producer=new Producer();
     
       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;
           }
       });
               proxyProducer.saleProduct(12000f);

   }
}

2、基於子類的動態代理

/**
 * 動態代理:
 *  特點:位元組碼隨用隨建立,隨用隨載入
 *  作用:不修改原始碼的基礎上對方法增強
 *  分類:
 *      基於介面的動態代理
 *      基於子類的動態代理
 *  基於子類的動態代理:
 *      涉及的類:Enhancer
 *      提供者:第三方cglib庫
 *  如何建立代理物件:
 *      使用Enhancer類中的create方法
 *  建立代理物件的要求:
 *      被代理類不能是最終類
 *  create方法的引數:
 *      Class:位元組碼
 *          它是用於指定被代理物件的位元組碼。
 *
 *      Callback:用於提供增強的程式碼
 *          它是讓我們寫如何代理。我們一般都是些一個該介面的實現類,通常情況下都是匿名內部類,但不是必須的。
 *          此介面的實現類都是誰用誰寫。
 *          我們一般寫的都是該介面的子介面實現類:MethodInterceptor
 */
package com.cc.cglib;

/**
 * 一個生產者
 */
public class Producer {
    /**
     * 銷售
     */
    public void saleProduct(float money){
        System.out.println("銷售產品,拿到錢:"+money);
    }

    /**
     * 售後
     */
    public void afterService(float money){
        System.out.println("提供售後服務,並拿到錢"+money);
    }
}
package com.cc.cglib;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import org.junit.Test;

import java.lang.reflect.Method;

/**
 * 模擬一個消費者
 */
public class Client {
    @Test
    public void test(){
            final Producer producer = new Producer();

            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);
        }
}

測試結果如下:

相關推薦

動態代理知識

動態代理實現的兩種方式 給動態代理舉個栗子:例如我們平時買膝上型電腦,很多時候都是不從廠家拿貨,而是通過經銷商買電腦。代理

(轉)java的動態代理機制

spring throw system urn log enc before 代理類 三個參數 原文出自:http://www.cnblogs.com/xiaoluo501395377/p/3383130.html 在學習Spring的時候,我們知道Spring主要

java的動態代理機制

following space h264 owin ipc ava smr hot lower Oq耗喊都自稚剿8斷0ohttp://shequ.docin.com/txqq_073ec59204 掀承U智泛纖06劣z粕05寡http://www.facebolw.com

Java動態代理 深度

實現 接下來 href 新建 結構 str 如果 cat 子類 代理模式是設計模式中非常重要的一種類型,而設計模式又是編程中非常重要的知識點,特別是在業務系統的重構中,更是有舉足輕重的地位。代理模式從類型上來說,可以分為靜態代理和動態代理兩種類型。 今天我將用非常簡單易懂的

【轉】java的動態代理機制

bar 同時 @override returns 復制 exce ins com hello 在學習Spring的時候,我們知道Spring主要有兩大思想,一個是IoC,另一個就是AOP,對於IoC,依賴註入就不用多說了,而對於Spring的核心AOP來說,我們不但要知道怎

基於JDK的動態代理技術

end course log 些許 private provide url 模仿 ade 雖然對於Spring的基本思想Aop是基於動態代理和CGlib這一點很早就有所認識,但是什麽是動態代理卻不甚清楚。為了對Spring加深理解,我覺得好好學習一下java

java中動態代理原始碼

在研究程式碼之前,我們先看看一個例項,然後我們根據例項來進行原始碼研究。 例項程式碼如下: package com.jd.dynamicproxy.dynamicproxy; import java.io.Serializable; import java.lang.reflect.Inv

_141_Java_java的動態代理機制

在學習Spring的時候,我們知道Spring主要有兩大思想,一個是IoC,另一個就是AOP,對於IoC,依賴注入就不用多說了,而對於Spring的核心AOP來說,我們不但要知道怎麼通過AOP來滿足的我們的功能,我們更需要學習的是其底層是怎麼樣的一個原理,而AOP的原理就

Java動態代理機制

 在學習spring的時候,我們知道Spring主要有兩大思想,一個是IoC,另一個就是AOP,對於IoC,依賴注入就不用多說了,而對於Spring的核心AOP來說,我們不但要知道怎麼通過AOP來滿足的我們的功能,我們更需要學習的是其底層是怎麼樣的一個原理,而AOP的原理就是Java的動態代理機制,所以本篇

InvocationHandler和Proxy(Class)的動態代理機制

在學習Spring的時候,我們知道Spring主要有兩大思想,一個是IoC,另一個就是AOP,對於IoC,依賴注入就不用多說了,而對於Spring的核心AOP來說,我們不但要知道怎麼通過AOP來滿足的我們的功能,我們更需要學習的是其底層是怎麼樣的一個原理,而AOP的原理就

Java動態代理機制(JDK動態代理與CGLIB動態代理區別)

代理是一種常用的設計模式,其目的就是為其他物件提供一個代理以控制對某個物件的訪問。代理類負責為委託類預處理訊息,過濾訊息並轉發訊息,以及進行訊息被委託類執行後的後續處理。在講述動態代理前,我們先通過一個例子瞭解一下什麼是靜態代理,這裡以事務控制為例。 1.靜態

動態路由協議RIP,OSPF基礎知識,以及配置實驗驗證

多個 shadow star 下一跳 tle water 外交 協議 使用 動態路由:不需要手工寫路由,將各自的直連網段宣告出去,路由器之間就可以相互學習,如果路由表有變化則及時更新宣告給相鄰的路由器靜態路由 優點:精確轉發,由管理員手動控制 缺點:靈活性差動態路由特點

java代理機制(動態代理原理解析,簡單易懂!)

一.代理機制概念 1.代理機制是一種設計模式,分為靜態代理 與動態代理. 2.特徵:代理類與委託類有同樣的介面,代理類主要負責為委託類預處理訊息、過濾訊息、把訊息轉發給委託類,以及事後處理訊息等。 代理類的物件本身並不真正實現服務,而是通過呼叫委託類的物件的相關方法,來提供特

動態代理 靜態代理 代理模式(講的很好 淺顯易懂)

們在Java程式碼中定義的。 通常情況下, 靜態代理中的代理類和委託類會實現同一介面或是派生自相同的父類。 一、概述 1. 什麼是代理 我們大家都知道微商代理,簡單地說就是代替廠家賣商品,廠家“委託”代理為其銷售商品。關於微商代理,首先我們從他們那裡買東

java設定模式---代理模式--動態代理模式和cglib代理模式

代理模式使用場景 代理模式的定義:什麼是代理模式呢?代理模式是常用的Java設計模式,它的特徵是代理類與委託類有同樣的介面,代理類主要負責為委託類預處理訊息、過濾訊息、把訊息轉發給委託類,以及事後處理消息等。代理類和委託類之間通常會存在關聯關係,一個代理類的物件與一個委託類的物件關聯,代理類的物

代理模式(靜態代理動態代理的區別以及聯系)

sys 事務處理 getname 沒有 面向接口編程 簡單 關註 不知道 正是 原文鏈接:https://www.cnblogs.com/takumicx/p/9285230.html 1. 前言 代理模式可以說是生活中處處可見。比如說在攜程上定火車票,攜程在這裏就起到

代理模式:靜態代理、JDK動態代理與Cglib動態代理

1. 代理模式簡介分類 - 概念 ​ 代理,是為了在不修改目標物件的基礎上,增強目標方法的業務邏輯。 ​ 客戶類需要執行的是目標物件的目標方法,但是真正執行的是代理物件的代理方法,客戶類對目標物件的訪問是通過代理物件來實現的。當然,代理類與目標類需要實現同一個介面。 -

跨域問題相關知識(原生js和jquery兩種方法實現jsonp跨域)

syn con 加載 developer 兩種方法 ray exe 編寫 分組 1、同源策略 同源策略(Same origin policy),它是由Netscape提出的一個著名的安全策略。同源策略是一種約定,它是瀏覽器最核心也最基本的安全功能,如果缺少了同源策略,則瀏覽

火熱的足球廣告平臺代理模式

索引 根據 客戶 存在 自身 實現 搜索 還要 擁有 什麽是足球廣告平臺? 足球廣告平臺是一款連接廣告與受眾的新型平臺。   以往廣告通常需要找到一個擁有大量流量的媒體,一般有報紙、電視臺、微博大v、自媒體大v等。這類流量有個共同點,就是廣告主出相應費用,讓他們一次或者多次

(轉)dp動態規劃分類

fun balance card 給定 def bits eve 回文串 好的 dp動態規劃分類詳解 轉自:http://blog.csdn.NET/cc_again/article/details/25866971 動態規劃一直是ACM競賽中的重點,同時又是難點,因為