Rumah  >  Artikel  >  Java  >  Penguasaan lengkap proksi dinamik Java

Penguasaan lengkap proksi dinamik Java

WBOY
WBOYke hadapan
2022-07-26 13:55:021639semak imbas

Artikel ini membawakan anda pengetahuan yang berkaitan tentang java Proksi dinamik bermaksud bahawa perhubungan antara kelas proksi dan kelas sasaran ditentukan apabila program dijalankan dan pelanggan memanggilnya melalui kelas proksi. Kaedah objek sasaran adalah untuk mencipta objek proksi kelas sasaran secara dinamik seperti yang diperlukan semasa program berjalan. Berikut akan menerangkan prinsip dan pelaksanaan proksi dinamik Java secara terperinci melalui kes saya harap ia akan membantu semua orang.

Penguasaan lengkap proksi dinamik Java

Kajian yang disyorkan: "tutorial video java"

Saya percaya semua orang biasa dengan perkataan "ejen". ringkasnya, ia adalah Jual barang bagi pihak pengilang, ejen menjual barangan bagi pihak pengilang, dan pelanggan mencari ejen untuk membeli barangan. Maksudnya: 1) Hubungan antara pelanggan dan pengilang tidak dapat dilihat, dan pelanggan tidak tahu siapa pengilang di belakangnya. 2) Ejen boleh "meletakkan" pelanggan dan menjual kepada kumpulan pelanggan yang memerlukan dengan lebih tepat.

Mod proksi

Mod proksi: Menyediakan proksi untuk objek lain untuk mengawal akses kepada objek ini, iaitu, mencipta objek proksi sebagai perantara antara klien dan objek sasaran, terutamanya tujuannya adalah untuk melindungi objek sasaran atau meningkatkan objek sasaran

Dengan menggunakan corak proksi, biasanya terdapat dua kelebihan:

1) Pelaksanaan kelas proksi boleh disembunyikan

2) Ia boleh merealisasikan penyahgandingan antara klien dan kelas proksi, dan boleh melakukan beberapa pemprosesan tambahan tanpa mengubah suai kod kelas proksi

Proksi statik

Apa yang dipanggil proksi dinamik adalah melalui pengisytiharan Kelas proksi yang jelas digunakan untuk mengakses objek sumber Satu proksi hanya boleh melayani satu produk Apabila terdapat n produk, n proksi diperlukan, yang tidak kondusif untuk pembangunan perniagaan.

Contoh: Kami mempunyai dua antara muka, Tetikus dan Papan Kekunci, setiap antara muka mempunyai kelas pelaksanaan

Kod dalam kelas pelaksanaan adalah seperti berikut:

public class LogitechMouse implements Mouse{
    @Override
    public void sell() {
        System.out.println("出售罗技鼠标");
    }
}
public class HHKBKeyboard implements Keyboard{
    @Override
    public void sell() {
        System.out.println("出售HHKB键盘");
    }
}

Sekarang apa yang kita perlu lakukan ialah membiarkan ejen mengeluarkan ayat pemahaman pra-jualan sebelum memanggil sell(), dan ayat perkhidmatan selepas jualan selepas memanggil

Kemudian kami Hanya menulis dua kelas proksi MouseProxy dan KeyboardProxy

public class MouseProxy implements Mouse {
    private Mouse mouse;

    public MouseProxy(Mouse mouse) {
        this.mouse = mouse;
    }
    @Override
    public void sell() {
        System.out.println("售前了解");
        mouse.sell();
        System.out.println("售后服务");
    }
}
public class KeyboardProxy implements Keyboard{
    private Keyboard keyboard;
    public KeyboardProxy(Keyboard keyboard) {
        this.keyboard = keyboard;
    }
    @Override
    public void sell() {
        System.out.println("售前了解");
        keyboard.sell();
        System.out.println("售后服务");
    }
}

Pelaksanaan akhir ialah:

public class Test {
    public static void main(String[] args) {
        Mouse logitechMouse = new LogitechMouse();
        MouseProxy mouseProxy = new MouseProxy(logitechMouse);
        mouseProxy.sell();
        Keyboard hhkbKeyboard = new HHKBKeyboard();
        KeyboardProxy keyboardProxy = new KeyboardProxy(hhkbKeyboard);
        keyboardProxy.sell();
    }
}

Output:
Pemahaman pra-jualan
Tetikus Logitech untuk dijual
Perkhidmatan selepas jualan
Pemahaman pra-jualan
Papan kekunci HHKB untuk dijual
Perkhidmatan selepas jualan

Kod proksi statik adalah sangat mudah dan mudah difahami Walaupun model ini bagus, tetapi Terdapat juga kelemahan yang jelas:

  • Akan terdapat sejumlah besar kelas proksi yang berlebihan dua antara muka di sini Jika terdapat n antara muka, maka n kelas proksi mesti ditakrifkan.
  • Ia bukan mudah untuk dikekalkan Setelah antara muka berubah, kedua-dua kelas proksi dan kelas proksi mesti ditukar.

Kemudian anda boleh menggunakan proksi dinamik untuk menyelesaikan masalah pada masa ini

Proksi dinamik

Cara kelas proksi mencipta proksi semasa program dijalankan ialah dipanggil proksi dinamik, iaitu Dikatakan bahawa kelas proksi tidak ditakrifkan dalam kod java, tetapi dijana secara dinamik pada masa jalan

proksi dinamik JDK

JDK telah menyokong penciptaan proksi dinamik kelas sejak versi 1.3. Terdapat hanya 2 kelas teras utama: java.lang.reflect.Proxy dan java.lang.reflect.InvocationHandler

Masih contoh di atas, menggunakan proksi dinamik JDK seperti berikut:

public class JDKProxy implements InvocationHandler {
    private Object object;
    public JDKProxy(Object object) {
        this.object = object;
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("售前了解");
        Object invoke = method.invoke(object, args);
        System.out.println("售后服务");
        return invoke;
    }
}

Apabila kita memanggil kaedah proksi objek kelas, "Panggilan" ini akan dimajukan kepada kaedah panggilan

Objek kelas proksi dihantar sebagai parameter proksi Kaedah parameter

mengenal pasti kaedah kelas proksi yang kami sedang memanggil secara khusus

args ialah parameter kaedah ini.

Dengan cara ini, semua panggilan kami kepada kaedah dalam kelas proksi akan menjadi panggilan untuk memanggil, supaya kami boleh menambah logik pemprosesan bersatu pada kaedah panggilan (kami juga boleh memanggil ejen yang berbeza berdasarkan parameter kaedah) kaedah kelas melakukan pemprosesan yang berbeza). Oleh itu, kita boleh melaksanakan pemahaman pra-jualan dalam kaedah invoke kelas perantara, kemudian memanggil kaedah kelas proksi, dan kemudian menyediakan perkhidmatan selepas jualan.

Laksanakan kod

public class Test {
    public static void main(String[] args) {
        Mouse logitechMouse = new LogitechMouse();
        JDKProxy jdkProxy = new JDKProxy(logitechMouse);
        Mouse mouse= (Mouse)Proxy.newProxyInstance(jdkProxy.getClass().getClassLoader(), new Class[]{Mouse.class}, jdkProxy);
        mouse.sell();
        HHKBKeyboard hhkbKeyboard = new HHKBKeyboard();
        JDKProxy jdkProxy1 = new JDKProxy(hhkbKeyboard);
        Keyboard keyboard = (Keyboard)Proxy.newProxyInstance(jdkProxy1.getClass().getClassLoader(), new Class[]{Keyboard.class}, jdkProxy1);
        keyboard.sell();
    }
}

Anda dapat melihat bahawa tidak kira berapa banyak antara muka yang ada, hanya satu kelas proksi diperlukan.

Proksi dinamik CGLIB

Kelas proksi:

public class CGLIBProcy implements MethodInterceptor {
    private Enhancer enhancer = new Enhancer();
    private Object object;
    public CGLIBProcy(Object object) {
        this.object = object;
    }
    public Object getProxy(){
        //设置需要创建子类的类
        enhancer.setSuperclass(object.getClass());
        enhancer.setCallback(this);
        //创建代理对象
        return enhancer.create();
    }
    // o: cglib 动态生成的代理类的实例
    // method:实体类所调用的都被代理的方法的引用
    // objects 参数列表
    // methodProxy:生成的代理类对方法的代理引用
    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        System.out.println("售前了解");
        Object invoke = method.invoke(object, objects);
        System.out.println("售后处理");
        return invoke;
    }
}

Kod pelaksanaan:

public class Test {
    public static void main(String[] args) {
        Mouse logitechMouse = new LogitechMouse();
        CGLIBProcy cglibProcy = new CGLIBProcy(logitechMouse);
        Mouse proxy = (Mouse)cglibProcy.getProxy();
        proxy.sell();
        cglibProcy = new CGLIBProcy(new HHKBKeyboard());
        Keyboard keyboard = (Keyboard)cglibProcy.getProxy();
        keyboard.sell();
    }
}

Perbezaan antara proksi JDK dan proksi CGLIB

  • Proksi dinamik JDK melaksanakan antara muka, idea warisan dinamik CGLIB
  • Proksi dinamik JDK (apabila objek sasaran mempunyai antara muka) kecekapan pelaksanaan lebih tinggi daripada CIGLIB
  • Jika objek mempunyai pelaksanaan antara muka, pilih Ejen JDK, jika tiada pelaksanaan antara muka, pilih ejen CGILB

Pembelajaran yang disyorkan: "tutorial video java"

Atas ialah kandungan terperinci Penguasaan lengkap proksi dinamik Java. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Artikel ini dikembalikan pada:jb51.net. Jika ada pelanggaran, sila hubungi admin@php.cn Padam