Rumah Java javaTutorial java代理模式与动态代理模式详解

java代理模式与动态代理模式详解

Feb 07, 2017 pm 01:40 PM

1、代理模式

所谓代理,就是一个人或者一个机构代表另一个人或者另一个机构采取行动。在一些情况下,一个客户不想或者不能够直接引用一个对象,而代理对象可以在客户端和目标对象之前起到中介的作用。
代理模式给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用。

生活中的例子:过年加班比较忙,没空去买火车票,这时可以打个电话到附近的票务中心,叫他们帮你买张回家的火车票,当然这会附加额外的劳务费。但要清楚票务中心自己并不卖票,只有火车站才真正卖票,票务中心卖给你的票其实是通过火车站实现的。这点很重要!

上面这个例子,你就是“客户”,票务中心就是“代理角色”,火车站是“真实角色”,卖票称为“抽象角色”!


代理模式JAVA代码示例:
抽象角色:抽象类或接口

interface Business  
{  
    void doAction();  
}
Salin selepas log masuk

真实角色:真正实现了业务逻辑接口

代理角色:自己并未实现业务逻辑接口,而是调用真实角色来实现

class BusinessImplProxy implements Business  
{  
    private BusinessImpl bi;  
    public void doAction()  
    {  
        if (bi==null)  
        {  
            bi = new BusinessImpl();  
        }  
        doBefore();  
        bi.doAction();  
        doAfter();  
    }  
    public void doBefore()  
    {  
        System.out.println("前置处理!");  
    }  
    public void doAfter()  
    {  
        System.out.println("后置处理!");  
    }  
}  
//测试类  
class Test  
{  
    public static void main(String[] args)  
    {  
        //引用变量定义为抽象角色类型  
        Business bi = new BusinessImplProxy();  
        bi.doAction();  
    }  
}
Salin selepas log masuk
<span></span>
Salin selepas log masuk

所以,借助于JVM的支持,可以在运行时动态生成代理类(“代理角色”),我们就可以解决上述代理模式中代码膨胀的问题,使用了动态代理后,“代理角色”将不用手动生成,而由JVM在运行时,通过指定类加载器、接口数组、调用处理程序这3个参数来动态生成。

动态代理模式JAVA代码示例:

import java.lang.reflect.InvocationHandler;
 import java.lang.reflect.Proxy;
 import java.lang.reflect.Method;
 //抽象角色:java动态代理的实现目前只支持接口,不支持抽象类
 interface BusinessFoo
 {
     void foo();
 }
 interface BusinessBar
{
    String bar(String message);
}
//真实角色:真正实现业务逻辑方法
class BusinessFooImpl implements BusinessFoo
{
    public void foo()
    {
        System.out.println("BusinessFooImpl.foo()");
    }
}
class BusinessBarImpl implements BusinessBar
{
    public String bar(String message)
    {
        System.out.println("BusinessBarImpl.bar()");
        return message;
    }
}
//动态角色:动态生成代理类
class BusinessImplProxy implements InvocationHandler
{
    private Object obj;
    BusinessImplProxy() {
    }
    BusinessImplProxy(Object obj) {
        this.obj = obj;
    }
    public Object invoke(Object proxy,Method method,Object[] args) throws Throwable
    {
        Object result = null;
        doBefore();
        result = method.invoke(obj,args);
        doAfter();
        return result;
    }
    public void doBefore(){
        System.out.println("do something before Business Logic");
    }
    public void doAfter(){
        System.out.println("do something after Business Logic");
    }
    public static Object factory(Object obj)
    {
        Class cls = obj.getClass();
        return Proxy.newProxyInstance(cls.getClassLoader(),cls.getInterfaces(),new BusinessImplProxy(obj));
    }
}
//测试类
public class DynamicProxy
{    
    public static void main(String[] args) throws Throwable
    {
        BusinessFooImpl bfoo = new BusinessFooImpl();
        BusinessFoo bf = (BusinessFoo)BusinessImplProxy.factory(bfoo);
        bf.foo();
        System.out.println();

        BusinessBarImpl bbar = new BusinessBarImpl();
        BusinessBar bb = (BusinessBar)BusinessImplProxy.factory(bbar);
        String message = bb.bar("Hello,World");
        System.out.println(message);
    }
}
Salin selepas log masuk

程序流程说明:
new BusinessFooImpl();创建一个“真实角色”,传递给工厂方法BusinessImplProxy.factory(),进而初始化“调用处理器”——即实现InvocationHandler的类。并返回一个动态创建的代理类实例,由于“代理角色”也必然实现了“抽象角色”提供的业务逻辑方法,故可向下转型为BusinessBar,并赋值给指向BusinessBar类型的引用bb。
newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h)方法由程序员来指定参数动态返回需要的代理类,而invoke(Object proxy, Method method, Object[] args) 方法则是由JVM在运行时动态调用的。当执行“bb.bar("Hello,World");”方法时,JVM动态指派“调用处理器”,向外层invoke传递参数,并调用method.invoke(obj,args)真正执行!

BusinessImplProxy.Factory静态方法用来动态生成代理类(“代理角色”),在运行时根据不同的业务逻辑接口BusinessFoo和BusinessBar,在运行时分别动态生成了代理角色。“抽象角色”、“代理角色”以及调用处理器(实现InvocationHandler接口的类)这三者都可以改变,所以说JAVA的动态代理十分强大。

更多java代理模式与动态代理模式详解相关文章请关注PHP中文网!

Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn

Alat AI Hot

Undresser.AI Undress

Undresser.AI Undress

Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover

AI Clothes Remover

Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool

Undress AI Tool

Gambar buka pakaian secara percuma

Clothoff.io

Clothoff.io

Penyingkiran pakaian AI

AI Hentai Generator

AI Hentai Generator

Menjana ai hentai secara percuma.

Artikel Panas

R.E.P.O. Kristal tenaga dijelaskan dan apa yang mereka lakukan (kristal kuning)
3 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Tetapan grafik terbaik
3 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Cara Memperbaiki Audio Jika anda tidak dapat mendengar sesiapa
3 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25: Cara Membuka Segala -galanya Di Myrise
4 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌

Alat panas

Notepad++7.3.1

Notepad++7.3.1

Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina

SublimeText3 versi Cina

Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1

Hantar Studio 13.0.1

Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6

Dreamweaver CS6

Alat pembangunan web visual

SublimeText3 versi Mac

SublimeText3 versi Mac

Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Bagaimanakah mekanisme kelas muatan Java berfungsi, termasuk kelas yang berbeza dan model delegasi mereka? Bagaimanakah mekanisme kelas muatan Java berfungsi, termasuk kelas yang berbeza dan model delegasi mereka? Mar 17, 2025 pm 05:35 PM

Kelas kelas Java melibatkan pemuatan, menghubungkan, dan memulakan kelas menggunakan sistem hierarki dengan bootstrap, lanjutan, dan pemuat kelas aplikasi. Model delegasi induk memastikan kelas teras dimuatkan dahulu, yang mempengaruhi LOA kelas tersuai

Bagaimanakah saya melaksanakan caching pelbagai peringkat dalam aplikasi java menggunakan perpustakaan seperti kafein atau cache jambu? Bagaimanakah saya melaksanakan caching pelbagai peringkat dalam aplikasi java menggunakan perpustakaan seperti kafein atau cache jambu? Mar 17, 2025 pm 05:44 PM

Artikel ini membincangkan pelaksanaan caching pelbagai peringkat di Java menggunakan kafein dan cache jambu untuk meningkatkan prestasi aplikasi. Ia meliputi persediaan, integrasi, dan faedah prestasi, bersama -sama dengan Pengurusan Dasar Konfigurasi dan Pengusiran PRA Terbaik

Bagaimanakah saya boleh menggunakan JPA (Java Constence API) untuk pemetaan objek-objek dengan ciri-ciri canggih seperti caching dan malas malas? Bagaimanakah saya boleh menggunakan JPA (Java Constence API) untuk pemetaan objek-objek dengan ciri-ciri canggih seperti caching dan malas malas? Mar 17, 2025 pm 05:43 PM

Artikel ini membincangkan menggunakan JPA untuk pemetaan objek-relasi dengan ciri-ciri canggih seperti caching dan pemuatan malas. Ia meliputi persediaan, pemetaan entiti, dan amalan terbaik untuk mengoptimumkan prestasi sambil menonjolkan potensi perangkap. [159 aksara]

Bagaimanakah saya menggunakan Maven atau Gradle untuk Pengurusan Projek Java Lanjutan, Membina Automasi, dan Resolusi Ketergantungan? Bagaimanakah saya menggunakan Maven atau Gradle untuk Pengurusan Projek Java Lanjutan, Membina Automasi, dan Resolusi Ketergantungan? Mar 17, 2025 pm 05:46 PM

Artikel ini membincangkan menggunakan Maven dan Gradle untuk Pengurusan Projek Java, membina automasi, dan resolusi pergantungan, membandingkan pendekatan dan strategi pengoptimuman mereka.

Bagaimanakah saya membuat dan menggunakan perpustakaan Java Custom (fail JAR) dengan pengurusan versi dan pergantungan yang betul? Bagaimanakah saya membuat dan menggunakan perpustakaan Java Custom (fail JAR) dengan pengurusan versi dan pergantungan yang betul? Mar 17, 2025 pm 05:45 PM

Artikel ini membincangkan membuat dan menggunakan perpustakaan Java tersuai (fail balang) dengan pengurusan versi dan pergantungan yang betul, menggunakan alat seperti Maven dan Gradle.

See all articles