最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

java動(dòng)態(tài)代理(jdk與cglib)詳細(xì)解析

 更新時(shí)間:2013年09月11日 08:42:40   作者:  
靜態(tài)代理:由程序員創(chuàng)建或特定工具自動(dòng)生成源代碼,再對(duì)其編譯。在程序運(yùn)行前,代理類的.class文件就已經(jīng)存在了

JAVA的動(dòng)態(tài)代理

代理模式
代理模式是常用的java設(shè)計(jì)模式,他的特征是代理類與委托類有同樣的接口,代理類主要負(fù)責(zé)為委托類預(yù)處理消息、過濾消息、把消息轉(zhuǎn)發(fā)給委托類,以及事后處理消息等。代理類與委托類之間通常會(huì)存在關(guān)聯(lián)關(guān)系,一個(gè)代理類的對(duì)象與一個(gè)委托類的對(duì)象關(guān)聯(lián),代理類的對(duì)象本身并不真正實(shí)現(xiàn)服務(wù),而是通過調(diào)用委托類的對(duì)象的相關(guān)方法,來提供特定的服務(wù)。
按照代理的創(chuàng)建時(shí)期,代理類可以分為兩種。

靜態(tài)代理:由程序員創(chuàng)建或特定工具自動(dòng)生成源代碼,再對(duì)其編譯。在程序運(yùn)行前,代理類的.class文件就已經(jīng)存在了。

動(dòng)態(tài)代理:在程序運(yùn)行時(shí),運(yùn)用反射機(jī)制動(dòng)態(tài)創(chuàng)建而成。 

首先看一下靜態(tài)代理:
1、Count.java

復(fù)制代碼 代碼如下:

package net.battier.dao; 

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

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



2、CountImpl.java
復(fù)制代碼 代碼如下:

package net.battier.dao.impl; 

import net.battier.dao.Count; 

/**
 * 委托類(包含業(yè)務(wù)邏輯)
 * 
 * @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; 

/**
 * 這是一個(gè)代理類(增強(qiáng)CountImpl實(shí)現(xiàn)類)
 * 
 * @author Administrator
 * 
 */ 
public class CountProxy implements Count { 
    private CountImpl countImpl; 

    /**
     * 覆蓋默認(rèn)構(gòu)造器
     * 
     * @param countImpl
     */ 
    public CountProxy(CountImpl countImpl) { 
        this.countImpl = countImpl; 
    } 

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

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

    } 



3、TestCount.java
復(fù)制代碼 代碼如下:

package net.battier.test; 

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

/**
 *測(cè)試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(); 

    } 


觀察代碼可以發(fā)現(xiàn)每一個(gè)代理類只能為一個(gè)接口服務(wù),這樣一來程序開發(fā)中必然會(huì)產(chǎn)生過多的代理,而且,所有的代理操作除了調(diào)用的方法不一樣之外,其他的操作都一樣,則此時(shí)肯定是重復(fù)代碼。解決這一問題最好的做法是可以通過一個(gè)代理類完成全部的代理功能,那么此時(shí)就必須使用動(dòng)態(tài)代理完成。

再來看一下動(dòng)態(tài)代理:
JDK動(dòng)態(tài)代理中包含一個(gè)類和一個(gè)接口:
InvocationHandler接口:
public interface InvocationHandler {
public Object invoke(Object proxy,Method method,Object[] args) throws Throwable;
}
參數(shù)說明:
Object proxy:指被代理的對(duì)象。
Method method:要調(diào)用的方法
Object[] args:方法調(diào)用時(shí)所需要的參數(shù)

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

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

Ps:類加載器
在Proxy類中的newProxyInstance()方法中需要一個(gè)ClassLoader類的實(shí)例,ClassLoader實(shí)際上對(duì)應(yīng)的是類加載器,在Java中主要有一下三種類加載器;
Booststrap ClassLoader:此加載器采用C++編寫,一般開發(fā)中是看不到的;
Extendsion ClassLoader:用來進(jìn)行擴(kuò)展類的加載,一般對(duì)應(yīng)的是jre\lib\ext目錄中的類;
AppClassLoader:(默認(rèn))加載classpath指定的類,是最常使用的是一種加載器。

動(dòng)態(tài)代理
與靜態(tài)代理類對(duì)照的是動(dòng)態(tài)代理類,動(dòng)態(tài)代理類的字節(jié)碼在程序運(yùn)行時(shí)由Java反射機(jī)制動(dòng)態(tài)生成,無(wú)需程序員手工編寫它的源代碼。動(dòng)態(tài)代理類不僅簡(jiǎn)化了編程工作,而且提高了軟件系統(tǒng)的可擴(kuò)展性,因?yàn)镴ava 反射機(jī)制可以生成任意類型的動(dòng)態(tài)代理類。java.lang.reflect 包中的Proxy類和InvocationHandler 接口提供了生成動(dòng)態(tài)代理類的能力。

動(dòng)態(tài)代理示例:
1、BookFacade.java

復(fù)制代碼 代碼如下:

package net.battier.dao; 

public interface BookFacade { 
    public void addBook(); 
}

2、BookFacadeImpl.java
復(fù)制代碼 代碼如下:

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動(dòng)態(tài)代理代理類
 * 
 * @author student
 * 
 */ 
public class BookFacadeProxy implements InvocationHandler { 
    private Object target; 
    /**
     * 綁定委托對(duì)象并返回一個(gè)代理類
     * @param target
     * @return
     */ 
    public Object bind(Object target) { 
        this.target = target; 
        //取得代理對(duì)象 
        return Proxy.newProxyInstance(target.getClass().getClassLoader(), 
                target.getClass().getInterfaces(), this);   //要綁定接口(這是一個(gè)缺陷,cglib彌補(bǔ)了這一缺陷) 
    } 

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



3、TestProxy.java
復(fù)制代碼 代碼如下:

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的動(dòng)態(tài)代理依靠接口實(shí)現(xiàn),如果有些類并沒有實(shí)現(xiàn)接口,則不能使用JDK代理,這就要使用cglib動(dòng)態(tài)代理了。

Cglib動(dòng)態(tài)代理
JDK的動(dòng)態(tài)代理機(jī)制只能代理實(shí)現(xiàn)了接口的類,而不能實(shí)現(xiàn)接口的類就不能實(shí)現(xiàn)JDK的動(dòng)態(tài)代理,cglib是針對(duì)類來實(shí)現(xiàn)代理的,他的原理是對(duì)指定的目標(biāo)類生成一個(gè)子類,并覆蓋其中方法實(shí)現(xiàn)增強(qiáng),但因?yàn)椴捎玫氖抢^承,所以不能對(duì)final修飾的類進(jìn)行代理。

示例
1、BookFacadeCglib.java

復(fù)制代碼 代碼如下:

package net.battier.dao; 

public interface BookFacade { 
    public void addBook(); 


2、BookCadeImpl1.java
復(fù)制代碼 代碼如下:

package net.battier.dao.impl; 

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


3、BookFacadeProxy.java
復(fù)制代碼 代碼如下:

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動(dòng)態(tài)代理
 * 
 * @author student
 * 
 */ 
public class BookFacadeCglib implements MethodInterceptor { 
    private Object target; 

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

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

 
    } 



4、TestCglib.java
復(fù)制代碼 代碼如下:

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

相關(guān)文章

  • Java分別利用深度優(yōu)先和廣度優(yōu)先求解迷宮路徑

    Java分別利用深度優(yōu)先和廣度優(yōu)先求解迷宮路徑

    這篇文章主要為大家詳細(xì)介紹了Java如何利用深度優(yōu)先的非遞歸遍歷方法和廣度優(yōu)先的遍歷方法實(shí)現(xiàn)求解迷宮路徑,文中的示例代碼講解詳細(xì),需要的可以參考一下
    2022-08-08
  • Java IO流對(duì)象的序列化和反序列化實(shí)例詳解

    Java IO流對(duì)象的序列化和反序列化實(shí)例詳解

    這篇文章主要介紹了Java IO流對(duì)象的序列化和反序列化實(shí)例詳解的相關(guān)資料,需要的朋友可以參考下
    2017-05-05
  • Java基本數(shù)據(jù)類型與類型轉(zhuǎn)換實(shí)例分析

    Java基本數(shù)據(jù)類型與類型轉(zhuǎn)換實(shí)例分析

    這篇文章主要介紹了Java基本數(shù)據(jù)類型與類型轉(zhuǎn)換,結(jié)合實(shí)例形式分析了Java基本數(shù)據(jù)類型分類、用法,類型轉(zhuǎn)換及相關(guān)操作注意事項(xiàng),需要的朋友可以參考下
    2020-04-04
  • SpringBoot中使用MyBatis詳細(xì)指南

    SpringBoot中使用MyBatis詳細(xì)指南

    MyBatis 是一款優(yōu)秀的持久層框架,它支持定制化 SQL、存儲(chǔ)過程以及高級(jí)映射,將 Spring Boot 和 MyBatis 集成,能夠充分發(fā)揮 Spring Boot 的快速開發(fā)特性和 MyBatis 靈活的數(shù)據(jù)庫(kù)操作能力,本文給大家介紹了SpringBoot使用MyBatis詳細(xì)指南,需要的朋友可以參考下
    2025-01-01
  • Java 8 lambda初試示例詳解

    Java 8 lambda初試示例詳解

    這篇文章主要介紹了Java 8 lambda初試示例詳解,需要的朋友可以參考下
    2017-04-04
  • Java 進(jìn)程執(zhí)行外部程序造成阻塞的一種原因

    Java 進(jìn)程執(zhí)行外部程序造成阻塞的一種原因

    前一陣子在研究文檔展示時(shí)使用了java進(jìn)程直接調(diào)用外部程序,其中遇到一個(gè)問題花了好長(zhǎng)時(shí)間才解決,這個(gè)問題就是外部程序直接執(zhí)行沒什么問題,但是當(dāng)使用Java進(jìn)程執(zhí)行時(shí)外部程序就阻塞在那兒不動(dòng)了。而且這個(gè)外部程序在處理某些文件時(shí)使用Java進(jìn)程執(zhí)行是沒問題的
    2014-03-03
  • java動(dòng)態(tài)綁定和靜態(tài)綁定用法實(shí)例詳解

    java動(dòng)態(tài)綁定和靜態(tài)綁定用法實(shí)例詳解

    這篇文章主要介紹了java動(dòng)態(tài)綁定和靜態(tài)綁定用法,結(jié)合實(shí)例形式詳細(xì)分析了java動(dòng)態(tài)綁定與靜態(tài)綁定相關(guān)概念、原理、實(shí)現(xiàn)方法及使用注意事項(xiàng),需要的朋友可以參考下
    2019-05-05
  • Lombok中@Builder和@SuperBuilder注解的用法案例

    Lombok中@Builder和@SuperBuilder注解的用法案例

    @Builder?是?lombok?中的注解,可以使用builder()構(gòu)造的Person.PersonBuilder對(duì)象進(jìn)行鏈?zhǔn)秸{(diào)用,給所有屬性依次賦值,這篇文章主要介紹了Lombok中@Builder和@SuperBuilder注解的用法,需要的朋友可以參考下
    2023-01-01
  • 快速學(xué)會(huì)Dubbo的配置環(huán)境及相關(guān)配置

    快速學(xué)會(huì)Dubbo的配置環(huán)境及相關(guān)配置

    本文主要講解Dubbo的環(huán)境與配置,文中運(yùn)用大量代碼和圖片講解的非常詳細(xì),需要學(xué)習(xí)或用到相關(guān)知識(shí)的小伙伴可以參考這篇文章
    2021-09-09
  • java中多線程加鎖的四種方式

    java中多線程加鎖的四種方式

    Java中實(shí)現(xiàn)多線程安全的關(guān)鍵是加鎖,主要方式有synchronized關(guān)鍵字、ReentrantLock類、ReadWriteLock接口和Semaphore類,本文就來介紹一下這四種方式,感興趣的可以了解一下
    2024-10-10

最新評(píng)論

桑植县| 基隆市| 平乐县| 平陆县| 哈巴河县| 遵义县| 商南县| 吉林省| 双鸭山市| 绥宁县| 元阳县| 利川市| 金门县| 大石桥市| 布拖县| 高清| 嘉峪关市| 高清| 太康县| 泽库县| 晋州市| 襄樊市| 高要市| 台中县| 杂多县| 黄陵县| 枞阳县| 克山县| 平定县| 宜君县| 德保县| 大余县| 武陟县| 凤翔县| 兰溪市| 信阳市| 濮阳县| 二连浩特市| 白水县| 赤水市| 凯里市|