亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > Java > 正文

java動態代理(jdk與cglib)詳細解析

2019-11-26 15:58:30
字體:
來源:轉載
供稿:網友

JAVA的動態代理

代理模式
代理模式是常用的java設計模式,他的特征是代理類與委托類有同樣的接口,代理類主要負責為委托類預處理消息、過濾消息、把消息轉發給委托類,以及事后處理消息等。代理類與委托類之間通常會存在關聯關系,一個代理類的對象與一個委托類的對象關聯,代理類的對象本身并不真正實現服務,而是通過調用委托類的對象的相關方法,來提供特定的服務。
按照代理的創建時期,代理類可以分為兩種。

靜態代理:由程序員創建或特定工具自動生成源代碼,再對其編譯。在程序運行前,代理類的.class文件就已經存在了。

動態代理:在程序運行時,運用反射機制動態創建而成。 

首先看一下靜態代理:
1、Count.java

復制代碼 代碼如下:

package net.battier.dao; 

/**
 * 定義一個賬戶接口
 * 
 * @author Administrator
 * 
 */ 
public interface Count { 
    // 查看賬戶方法 
    public void queryCount(); 

    // 修改賬戶方法 
    public void updateCount(); 



2、CountImpl.java
復制代碼 代碼如下:

package net.battier.dao.impl; 

import net.battier.dao.Count; 

/**
 * 委托類(包含業務邏輯)
 * 
 * @author Administrator
 * 
 */ 
public class CountImpl implements Count { 

    @Override 
    public void queryCount() { 
        System.out.println("查看賬戶方法..."); 

    } 

    @Override 
    public void updateCount() { 
        System.out.println("修改賬戶方法..."); 

    } 



CountProxy.java 
package net.battier.dao.impl; 

import net.battier.dao.Count; 

/**
 * 這是一個代理類(增強CountImpl實現類)
 * 
 * @author Administrator
 * 
 */ 
public class CountProxy implements Count { 
    private CountImpl countImpl; 

    /**
     * 覆蓋默認構造器
     * 
     * @param countImpl
     */ 
    public CountProxy(CountImpl countImpl) { 
        this.countImpl = countImpl; 
    } 

    @Override 
    public void queryCount() { 
        System.out.println("事務處理之前"); 
        // 調用委托類的方法; 
        countImpl.queryCount(); 
        System.out.println("事務處理之后"); 
    } 

    @Override 
    public void updateCount() { 
        System.out.println("事務處理之前"); 
        // 調用委托類的方法; 
        countImpl.updateCount(); 
        System.out.println("事務處理之后"); 

    } 



3、TestCount.java
復制代碼 代碼如下:

package net.battier.test; 

import net.battier.dao.impl.CountImpl; 
import net.battier.dao.impl.CountProxy; 

/**
 *測試Count類
 * 
 * @author Administrator
 * 
 */ 
public class TestCount { 
    public static void main(String[] args) { 
        CountImpl countImpl = new CountImpl(); 
        CountProxy countProxy = new CountProxy(countImpl); 
        countProxy.updateCount(); 
        countProxy.queryCount(); 

    } 


觀察代碼可以發現每一個代理類只能為一個接口服務,這樣一來程序開發中必然會產生過多的代理,而且,所有的代理操作除了調用的方法不一樣之外,其他的操作都一樣,則此時肯定是重復代碼。解決這一問題最好的做法是可以通過一個代理類完成全部的代理功能,那么此時就必須使用動態代理完成。

再來看一下動態代理:
JDK動態代理中包含一個類和一個接口:
InvocationHandler接口:
public interface InvocationHandler {
public Object invoke(Object proxy,Method method,Object[] args) throws Throwable;
}
參數說明:
Object proxy:指被代理的對象。
Method method:要調用的方法
Object[] args:方法調用時所需要的參數

可以將InvocationHandler接口的子類想象成一個代理的最終操作類,替換掉ProxySubject。

Proxy類:
Proxy類是專門完成代理的操作類,可以通過此類為一個或多個接口動態地生成實現類,此類提供了如下的操作方法:
public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces,
InvocationHandler h)
                               throws IllegalArgumentException
參數說明:
ClassLoader loader:類加載器
Class<?>[] interfaces:得到全部的接口
InvocationHandler h:得到InvocationHandler接口的子類實例

Ps:類加載器
在Proxy類中的newProxyInstance()方法中需要一個ClassLoader類的實例,ClassLoader實際上對應的是類加載器,在Java中主要有一下三種類加載器;
Booststrap ClassLoader:此加載器采用C++編寫,一般開發中是看不到的;
Extendsion ClassLoader:用來進行擴展類的加載,一般對應的是jre/lib/ext目錄中的類;
AppClassLoader:(默認)加載classpath指定的類,是最常使用的是一種加載器。

動態代理
與靜態代理類對照的是動態代理類,動態代理類的字節碼在程序運行時由Java反射機制動態生成,無需程序員手工編寫它的源代碼。動態代理類不僅簡化了編程工作,而且提高了軟件系統的可擴展性,因為Java 反射機制可以生成任意類型的動態代理類。java.lang.reflect 包中的Proxy類和InvocationHandler 接口提供了生成動態代理類的能力。

動態代理示例:
1、BookFacade.java

復制代碼 代碼如下:

package net.battier.dao; 

public interface BookFacade { 
    public void addBook(); 
}

2、BookFacadeImpl.java
復制代碼 代碼如下:

package net.battier.dao.impl; 

import net.battier.dao.BookFacade; 

public class BookFacadeImpl implements BookFacade { 

    @Override 
    public void addBook() { 
        System.out.println("增加圖書方法。。。"); 
    } 



BookFacadeProxy.java 

package net.battier.proxy; 

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

/**
 * JDK動態代理代理類
 * 
 * @author student
 * 
 */ 
public class BookFacadeProxy implements InvocationHandler { 
    private Object target; 
    /**
     * 綁定委托對象并返回一個代理類
     * @param target
     * @return
     */ 
    public Object bind(Object target) { 
        this.target = target; 
        //取得代理對象 
        return Proxy.newProxyInstance(target.getClass().getClassLoader(), 
                target.getClass().getInterfaces(), this);   //要綁定接口(這是一個缺陷,cglib彌補了這一缺陷) 
    } 

    @Override 
    /**
     * 調用方法
     */ 
    public Object invoke(Object proxy, Method method, Object[] args) 
            throws Throwable { 
        Object result=null; 
        System.out.println("事物開始"); 
        //執行方法 
        result=method.invoke(target, args); 
        System.out.println("事物結束"); 
        return result; 
    } 



3、TestProxy.java
復制代碼 代碼如下:

package net.battier.test; 

import net.battier.dao.BookFacade; 
import net.battier.dao.impl.BookFacadeImpl; 
import net.battier.proxy.BookFacadeProxy; 

public class TestProxy { 

    public static void main(String[] args) { 
        BookFacadeProxy proxy = new BookFacadeProxy(); 
        BookFacade bookProxy = (BookFacade) proxy.bind(new BookFacadeImpl()); 
        bookProxy.addBook(); 
    } 



但是,JDK的動態代理依靠接口實現,如果有些類并沒有實現接口,則不能使用JDK代理,這就要使用cglib動態代理了。

Cglib動態代理
JDK的動態代理機制只能代理實現了接口的類,而不能實現接口的類就不能實現JDK的動態代理,cglib是針對類來實現代理的,他的原理是對指定的目標類生成一個子類,并覆蓋其中方法實現增強,但因為采用的是繼承,所以不能對final修飾的類進行代理。

示例
1、BookFacadeCglib.java

復制代碼 代碼如下:

package net.battier.dao; 

public interface BookFacade { 
    public void addBook(); 


2、BookCadeImpl1.java
復制代碼 代碼如下:

package net.battier.dao.impl; 

/**
 * 這個是沒有實現接口的實現類
 * 
 * @author student
 * 
 */ 
public class BookFacadeImpl1 { 
    public void addBook() { 
        System.out.println("增加圖書的普通方法..."); 
    } 


3、BookFacadeProxy.java
復制代碼 代碼如下:

package net.battier.proxy; 

import java.lang.reflect.Method; 

import net.sf.cglib.proxy.Enhancer; 
import net.sf.cglib.proxy.MethodInterceptor; 
import net.sf.cglib.proxy.MethodProxy; 

/**
 * 使用cglib動態代理
 * 
 * @author student
 * 
 */ 
public class BookFacadeCglib implements MethodInterceptor { 
    private Object target; 

    /**
     * 創建代理對象
     * 
     * @param target
     * @return
     */ 
    public Object getInstance(Object target) { 
        this.target = target; 
        Enhancer enhancer = new Enhancer(); 
        enhancer.setSuperclass(this.target.getClass()); 
        // 回調方法 
        enhancer.setCallback(this); 
        // 創建代理對象 
        return enhancer.create(); 
    } 

    @Override 
    // 回調方法 
    public Object intercept(Object obj, Method method, Object[] args, 
            MethodProxy proxy) throws Throwable { 
        System.out.println("事物開始"); 
        proxy.invokeSuper(obj, args); 
        System.out.println("事物結束"); 
        return null; 

 
    } 



4、TestCglib.java
復制代碼 代碼如下:

package net.battier.test; 

import net.battier.dao.impl.BookFacadeImpl1; 
import net.battier.proxy.BookFacadeCglib; 

public class TestCglib { 

    public static void main(String[] args) { 
        BookFacadeCglib cglib=new BookFacadeCglib(); 
        BookFacadeImpl1 bookCglib=(BookFacadeImpl1)cglib.getInstance(new BookFacadeImpl1()); 
        bookCglib.addBook(); 
    } 

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产精品午夜视频| 4438全国成人免费| 久久久久国产精品免费网站| 国产亚洲精品综合一区91| 自拍偷拍亚洲在线| 孩xxxx性bbbb欧美| 大荫蒂欧美视频另类xxxx| 欧美激情乱人伦一区| 日本高清+成人网在线观看| 国产精品成av人在线视午夜片| 国产精品吴梦梦| 91精品久久久久久久久久久久久| 久久视频在线播放| 九九热精品在线| 欧美亚洲国产成人精品| 2019中文在线观看| 成人黄色在线播放| 日韩av第一页| 亚洲级视频在线观看免费1级| 欧美野外猛男的大粗鳮| 欧美成年人网站| 日韩欧美极品在线观看| 久久精品成人一区二区三区| 国产欧美日韩亚洲精品| 久久久av亚洲男天堂| 91免费精品国偷自产在线| 欧美另类99xxxxx| 国产午夜精品久久久| 91精品国产亚洲| 久久97精品久久久久久久不卡| 亚州av一区二区| 午夜免费在线观看精品视频| 久久久国产视频| 欧美视频一区二区三区…| 北条麻妃一区二区在线观看| 日韩高清有码在线| 日韩在线观看免费| 狠狠躁18三区二区一区| 国产精品狼人色视频一区| 国产欧美精品一区二区三区-老狼| 精品久久久91| 日韩欧美在线免费| 久久精品男人天堂| 亚洲色图35p| 国产日产久久高清欧美一区| 一区二区亚洲精品国产| 国产区亚洲区欧美区| 久久在精品线影院精品国产| 国产女人18毛片水18精品| 黄色成人av在线| 亚洲男人天堂久| 亚洲第一中文字幕| 国产aⅴ夜夜欢一区二区三区| 日韩在线观看精品| 97超碰色婷婷| 成人av色在线观看| 亲子乱一区二区三区电影| 亚洲肉体裸体xxxx137| 日韩一中文字幕| 亚洲人成网站999久久久综合| 国外视频精品毛片| 成人做爽爽免费视频| 久久综合免费视频影院| 热久久美女精品天天吊色| 久久国产精品亚洲| 久久精品视频一| 欧美又大粗又爽又黄大片视频| 欧美性videos高清精品| 欧美激情性做爰免费视频| 日韩免费中文字幕| 成人黄色生活片| 国产成人精彩在线视频九色| 久久人人爽亚洲精品天堂| 国产精品成人av性教育| 黑人狂躁日本妞一区二区三区| 成人免费视频xnxx.com| 欧美性在线视频| 久久久久久久久网站| 91av在线播放| 国产精品午夜国产小视频| 亚洲精品国产精品国自产在线| 国产精品高清在线| 91啪国产在线| 欧美日韩美女在线| 亚洲免费电影在线观看| 日本伊人精品一区二区三区介绍| 成人福利免费观看| 国产成人拍精品视频午夜网站| 国产精品午夜一区二区欲梦| 最近更新的2019中文字幕| 色综合亚洲精品激情狠狠| 午夜精品三级视频福利| 日韩一级裸体免费视频| 国产日韩欧美影视| 6080yy精品一区二区三区| 国产在线久久久| 国产成人精品日本亚洲专区61| 亚洲女同精品视频| 中文字幕日韩在线视频| 亚洲欧美www| 91精品久久久久久久久久入口| 国产精品三级美女白浆呻吟| 国产精品专区h在线观看| 国产免费一区二区三区香蕉精| 精品亚洲aⅴ在线观看| 国产在线久久久| 亚洲福利在线播放| 国产精品福利在线观看| 日韩视频免费中文字幕| 亚洲 日韩 国产第一| 97av在线视频| 亚洲国产精品福利| 亚洲欧洲午夜一线一品| 国产精品一区二区三区免费视频| 91精品国产自产在线老师啪| 成人福利网站在线观看11| 亚洲老司机av| 91在线观看欧美日韩| 青青久久aⅴ北条麻妃| 川上优av一区二区线观看| 91亚洲精华国产精华| 96精品久久久久中文字幕| 精品一区二区亚洲| 91网站在线免费观看| 欧美视频裸体精品| 精品电影在线观看| 亚洲一区二区三区成人在线视频精品| 伊人久久综合97精品| 国产一区二区色| 久久久久一本一区二区青青蜜月| 亚洲资源在线看| 久久久久久久国产精品| 成人免费淫片aa视频免费| 丝袜一区二区三区| 欧美午夜www高清视频| 国产福利视频一区二区| 亚洲国产中文字幕在线观看| 97在线视频免费| 成人在线播放av| 亚洲电影第1页| 97视频色精品| 国产精品久久久久久超碰| 成人在线视频福利| 中文字幕一精品亚洲无线一区| 亚洲欧美日韩中文在线| 一区二区三区回区在观看免费视频| 久99九色视频在线观看| 高清视频欧美一级| 亚洲天堂av在线免费| 国产精品第一区| 日本一区二区在线免费播放| 在线观看国产精品淫| 亚洲欧美国产精品va在线观看| 久久偷看各类女兵18女厕嘘嘘| 国产精品久久久久久久久久99| 色狠狠久久aa北条麻妃| 国产精品久久久久久久久久久久| 欧美激情一区二区三级高清视频| 久久久久久久久久婷婷| 91免费在线视频网站| 日韩中文字在线| 在线观看亚洲视频| 国产精品中文字幕久久久| 亚洲欧美成人精品|