[Java]静态代理、动态代理(基于JDK1.8)

这篇具有很好参考价值的文章主要介绍了[Java]静态代理、动态代理(基于JDK1.8)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

【版权声明】未经博主同意,谢绝转载!(请尊重原创,博主保留追究权)
https://www.cnblogs.com/cnb-yuchen/p/18002823
出自【进步*于辰的博客】

参考笔记一,P83;笔记二,P75.4。

目录
  • 1、概述
  • 2、静态代理的两种形式
    • 2.1 面向接口
    • 2.2 面向继承
  • 3、动态代理的两种形式
    • 3.1 JDK动态代理
    • 3.2 Cglib动态代理
  • 最后

1、概述

什么是代理模式?“代理模式”指通过为目标对象(原代码)创建代理对象,将附加功能(附加代码)注入目标对象的方法,从而实现附加功能的设计模式,分为静态代理和动态代理。

什么是静态代理?“静态代理”指为目标类手动创建代理类的代理方式。

什么是动态代理?“动态代理”指在不变动原代码的情况下,通过反射动态创建代理对象的代理方式。(注:“反射”是动态代理的底层,不可见)

2、静态代理的两种形式

2.1 面向接口

特点:目标对象与代理对象隶属于同一接口。

看下述代码:
1、公共接口:目标类和代理类的公共接口。

interface IService {
    int transfer(int money);
}

2、目标类。

class Target implements IService {
    @Override
    public int transfer(int money) {
        System.out.println("转账金额:" + money);
        return 1;
    }
}

3、代理类。

class Proxy implements IService {
    private Target target;
    public Proxy(Target target) {
        this.target = target;
    }

    @Override
    public int transfer(int score) {
        System.out.println("打开事务");// 附加功能
        int x = target.transfer(score);
        System.out.println("关闭事务");
        return x;
    }
}

测试。

class Test {
    public static void main(String[] args) {
        Proxy proxy = new Proxy(new Target());// 创建代理对象
        int x = proxy.transfer(10);
        if (x > 0)
            System.out.println("转账成功");
        else
            System.out.println("转账失败");
    }
}

测试结果:
[Java]静态代理、动态代理(基于JDK1.8)

2.2 面向继承

特点:目标对象与代理对象是继承关系,代理对象继承于目标对象。

看下述代码:
1、目标类。

class Target {
    public int transfer(int money) {
        System.out.println("转账金额:" + money);
        return 1;
    }
}

3、代理类。

class Proxy extends Target {
    @Override
    public int transfer(int money) {
        System.out.println("打开事务");// 附加功能
        int x = super.transfer(money);
        System.out.println("关闭事务");
        return x;
    }
}

测试。

class Test {
    public static void main(String[] args) {
        Proxy proxy = new Proxy();// 创建代理对象
        int x = proxy.transfer(20);
        if (x > 0)
            System.out.println("转账成功");
        else
            System.out.println("转账失败");
    }
}

测试结果:
[Java]静态代理、动态代理(基于JDK1.8)

3、动态代理的两种形式

PS:静态代理需要手动创建代理类,进而创建代理对象,很冗余。换个思路,反射可以根据 Class 信息创建实例,故可以通过反射为目标对象创建代理对象,则无需创建代理类,这就是“动态代理”。

3.1 JDK动态代理

特点:面向接口,隶属于Java API

看下述代码:
1、公共接口。

/**
 * 目标对象与代理对象的公共接口
 * 注:因为JDK动态代理面向接口,故目标对象和代理对象实现于同一接口
 */
interface IService {
    int transfer(int money);
}

2、目标类。

class Target implements IService {
    @Override
    public int transfer(int money) {
        System.out.println("转账金额:" + money);
        return 1;
    }
}

测试。

class Test {
    public static void main(String[] args) {
        Target target = new Target();
        /**
         * 通过 newProxyInstance() 创建代理对象
         *     第一个参数是目标对象的类加载器,指定为哪个目标对象创建代理对象;
         *     第二个参数是目标对象实现的接口,指定目标对象和代理对象的公共接口;
         *     第三个参数是拦截器对象,指定用哪个拦截器来创建代理对象,需要实现 InvocationHandler 接口。
         */
        // 由于代理对象 proxy 是通过反射创建于JVM,并无类存在,故要上转为公共接口 IService
        IService proxyInstance = (IService) Proxy.newProxyInstance(target.getClass().getClassLoader(),
                target.getClass().getInterfaces(),
                new InvocationHandler() {
                    /**
                     * 代理(调用 transfer())时执行的方法
                     * @param proxy  代理对象,即 proxyInstance,暂不知如何使用
                     * @param method 目标对象的 Method 的 class 对象
                     * @param args   目标对象的 Method 的形参数组
                     */
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        System.out.println("打开事务");// 附加功能
                        // invoke() 是反射中 Method 对象执行时调用的方法,故动态代理是通过反射调用目标对象被代理的方法
                        Object result = method.invoke(target, args);
                        System.out.println("关闭事务");
                        return result;
                    }
                });// 创建代理对象
        int x = proxyInstance.transfer(50);
        if (x > 0)
            System.out.println("转账成功");
        else
            System.out.println("转账失败");
    }
}


测试结果:
[Java]静态代理、动态代理(基于JDK1.8)
可以用Lambda表达式进行简化。

3.2 Cglib动态代理

特点:面向继承,隶属于Spring API

看下述代码:
1、目标类。

class Target {
    public int transfer(int money) {
        System.out.println("转账金额:" + money);
        return 1;
    }
}

2、代理类。

/**
 * Cglib动态代理类,需实现接口 MethodInterceptor
 */
class DynamicProxy implements MethodInterceptor {
    private Object target;
    public DynamicProxy(Object target) {
        this.target = target;
    }
    public Object createProxy() {
        Enhancer proxy = new Enhancer();// Enhancer 类是一种类生成器
        proxy.setCallback(this);// 设置拦截器,指定回对象为自身(暂不理解)
        proxy.setSuperclass(target.getClass());// 设置父类,指定为哪个目标对象创建代理对象
        return proxy.create();// 创建代理对象
    }

    /**
     * 代理(调用 transfer())时执行的方法
     * @param proxy       代理对象,即 proxyInstance,暂不知如何使用
     * @param method      目标对象的 Method 的 class对象
     * @param args        目标对象的 Method 的参数数组
     * @param methodProxy 代理方法,即 Target.transfer(),暂不知如何使用
     */
    @Override
    public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
        System.out.println("打开事务");// 附加功能
        // invoke() 是反射中 Method 对象执行时调用的方法,故动态代理是通过反射调用目标对象被代理的方法
        Object result = method.invoke(target, args);
        System.out.println("关闭事务");
        return result;
    }
}

测试。

class Test {
    public static void main(String[] args) {
        Target target = new Target();
        Target proxyInstance = (Target) new DynamicProxy(target).createProxy();
        int x = proxyInstance.transfer(100);
        if (x > 0)
            System.out.println("转账成功");
        else
            System.out.println("转账失败");
    }
}


测试结果:
[Java]静态代理、动态代理(基于JDK1.8)

同样可以用Lambda表达式进行简化,不过代理对象的创建(proxy.create())需要对 Enhancer 类的属性进行一些设置,故进行了封装。

注意:JDK动态代理和Cglib动态代理皆可拦截所有方法,包括:toString()hashcode()。不能拦截由 final 修饰方法,如:getClass()

最后

本文中的例子是为了阐述静态代理和动态代理的实现思想、方便大家理解而简单举出的,不一定有实用性,大家自行扩展。

本文完结。文章来源地址https://www.toymoban.com/news/detail-837618.html

到了这里,关于[Java]静态代理、动态代理(基于JDK1.8)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 温故知新之:代理模式,静态代理和动态代理(JDK动态代理)

    代理模式可以在不修改被代理对象的基础上,通过扩展代理类,进行一些功能的附加与增强。 静态代理 是一种代理模式的实现方式,它在编译期间就已经确定了代理对象,需要为每一个被代理对象创建一个代理类。静态代理的实现比较简单,但是每个被代理对象都需要创建

    2024年02月11日
    浏览(48)
  • 静态代理、jdk、cglib动态代理 搞不清? 看这个文章就懂了

    代理模式是一种比较好的理解的设计模式。简单来说就是 : 我们使用代理对象来增强目标对象(target obiect),这样就可以在不修改原目标对象的前提下,提供额外的功能操作,扩展目标对象的功能。 将核心业务代码和非核心的公共代码分离解耦,提高代码可维护性,让被代理

    2024年02月14日
    浏览(42)
  • MAC(适用于M1,M2芯片)下载Java8(官方 ARM64 JDK1.8)安装、配置环境,支持动态切换JDK

    官方下载地址 https://www.oracle.com/cn/java/technologies/downloads/ 这个是官方新发布的适配了M1、M2芯片的ARM64版本的jdk8,再也不用去第三方下载了,也不用满世界的去找第三方jdk缺少的jar包了,而且更快更强!! 可以下载免安装版, 这样就可以配置多个版本的jdk了,配置如下 使配置

    2024年02月08日
    浏览(114)
  • Java代理模式——静态代理与动态代理

    代理模式允许你为其他对象提供一个代理,以控制对这个对象的访问。代理模式在不改变实际对象的情况下,可以在访问对象时添加额外的功能。 可以理解为代理模式为被代理对象创造了一个替身,调用者可以通过这个替身去实现这个被代理对象的功能,这个替身也可以为被

    2024年02月13日
    浏览(47)
  • Java——JDK动态代理

    动态代理(理解) 基于反射机制 举个例子,生活中一般在打官司的时候都会请代理律师,为什么要请律师呢?是因为开庭的时候大部人对于打官司没有经验,只会说出自己案件的陈述,并不会根据法律等争取自己权益的最大化,此时就可以请律师帮助自己不仅完成对案件的陈述

    2024年02月09日
    浏览(42)
  • Java中的代理模式(二)JDK动态代理

    大家好👋,我是极客涛😎,上一篇中我们对代理模式有两大类,静态代理和动态代理,对于静态代理相信大家都信手拈来。对于动态代理还有两种实现,一种是java原生的Jdk代理,一种是Cglib方式。因为涉及到源码解读,所以我也将分两期完成,本期主要讲讲JDK动态代理的实

    2024年01月22日
    浏览(41)
  • Java代理之jdk动态代理+应用场景实战

    本文将先介绍jdk动态代理的基本用法,并对其原理和注意事项予以说明。之后将以两个最常见的应用场景为例,进行代码实操。这两个应用场景分别是 拦截器 和 声明性接口 ,它们在许多开发框架中广泛使用。比如在spring和mybatis中均使用了拦截器模式,在mybatis中还利用动态

    2023年04月10日
    浏览(44)
  • 【Java】JDK动态代理实现原理

    代理模式 代理模式一般包含三个角色: Subject :主题对象,一般是一个接口,定义一些业务相关的基本方法。 RealSubject :具体的主题对象实现类,它会实现Subject接口中的方法。 Proxy :代理对象,里面包含一个RealSubject的引用,外部会通过这个代理对象,来实现RealSubject中方

    2024年02月08日
    浏览(41)
  • Java 代理模式详解,静态代理与动态代理的区别及优缺点

    代理模式是一种常用的设计模式,它允许通过引入一个代理对象来控制对目标对象的访问。在Java中,代理模式被广泛应用,它可以提供额外的功能,如权限检查、缓存、日志记录等,同时还能在不修改目标对象的情况下对其进行扩展。 代理模式(Proxy Pattern)是指通过代理对象

    2024年02月11日
    浏览(44)
  • 【面试精讲】Java动态代理是如何实现的?JDK Proxy 和 CGLib 有什么区别?

    Java动态代理是如何实现的?JDK Proxy 和 CGLib 有什么区别? 一、Java动态代理的实现 1、使用JDK Proxy实现动态代理 2、使用CGLib实现动态代理 二、JDK Proxy 与 CGLib 的区别 三、Spring中的动态代理 四、 Lombok代理原理 总结 本文深入探讨了Java动态代理的实现机制,分别介绍了使用JDK

    2024年03月14日
    浏览(46)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包