我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Java实现动态代理的实例代码

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Java实现动态代理的实例代码

前言

动态代理在Java中有着广泛的应用,比如Spring AOP、Hibernate数据查询、测试框架的后端mock、RPC远程调用、Java注解对象获取、日志、用户鉴权、全局性异常处理、性能监控,甚至事务处理等。

代理,指的是使用代理对象代替对其它对象的访问,简单点说,你求职时找的中介就是代理,那么在Java中,代理如何体现呢?

静态代理

我们首先需要知道,何为静态代理?静态代理指的是在编译期就对目标对象的方法进行增强,例如:


public class TestDemo {

    interface EmailService {
        void sendEmail(String emailContent);
    }

    static class EmailServiceImpl implements EmailService{

        @Override
        public void sendEmail(String emailContent) {
            System.out.println("发送了一封邮件,内容为:" + emailContent);
        }
    }

    public static void main(String[] args) {
        EmailService emailService = new EmailServiceImpl();
        emailService.sendEmail("hello");
    }
}

现在若是想在发送邮件之前获取一下当前的时间,则可以使用代理类对发邮件的方法进行增强:


public class TestDemo {

    interface EmailService {
        void sendEmail(String emailContent);
    }

    static class EmailServiceImpl implements EmailService{

        @Override
        public void sendEmail(String emailContent) {
            System.out.println("发送了一封邮件,内容为:" + emailContent);
        }
    }

    static class EmailProxy implements EmailService{

        private final EmailService emailService;

        public EmailProxy(EmailService emailService) {
            this.emailService = emailService;
        }

        @Override
        public void sendEmail(String emailContent) {
            System.out.println(LocalDateTime.now());
            emailService.sendEmail(emailContent);
        }
    }

    public static void main(String[] args) {
        EmailService emailProxy = new EmailProxy(new EmailServiceImpl());
        emailProxy.sendEmail("hello");
    }
}

静态代理的缺点非常明显,编写麻烦,且可扩展性不强,而动态代理的出现,将彻底解决这些问题。

动态代理

动态代理与静态代理恰恰相反,动态代理是在运行期对目标对象的某个方法进行增强,比如仍然是发邮件的服务,使用动态代理,即可这样实现:


public class TestDemo {

    interface EmailService {
        void sendEmail(String emailContent);
    }

    static class EmailServiceImpl implements EmailService {

        @Override
        public void sendEmail(String emailContent) {
            System.out.println("发送了一封邮件,内容为:" + emailContent);
        }
    }

    public static void main(String[] args) {
        EmailService emailService = new EmailServiceImpl();
        EmailService emailProxy = (EmailService) Proxy.newProxyInstance(EmailServiceImpl.class.getClassLoader(), EmailServiceImpl.class.getInterfaces(), new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                System.out.println(LocalDateTime.now());
                Object result = method.invoke(emailService, args);
                return result;
            }
        });
        emailProxy.sendEmail("hello");
    }
}

使用JDK提供的Proxy和InvocationHandler类能够轻松实现动态代理,但这种方式也是有局限性的,就是被增强的类必须实现了接口,因为Proxy的参数中需要接收类的接口信息。

CGLib实现动态代理

CGLib的出现,打破了这一僵局,使用CGLib,能够增强任意的对象方法,即使你没有实现任何接口,因为它是通过继承的方式进行增强的。

下面就来演示一下如何使用CGLib,首先引入依赖:


<dependency>
    <groupId>cglib</groupId>
    <artifactId>cglib</artifactId>
    <version>3.3.0</version>
</dependency>

实现如下:


public class TestDemo {

    static class EmailServiceImpl {
        public void sendEmail(String emailContent) {
            System.out.println("发送了一封邮件,内容为:" + emailContent);
        }
    }

    public static void main(String[] args) {
        EmailServiceImpl emailService = new EmailServiceImpl();
        EmailServiceImpl emailProxy = (EmailServiceImpl) Enhancer.create(emailService.getClass(), new MethodInterceptor() {
            @Override
            public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
                System.out.println(LocalDateTime.now());
                Object obj = methodProxy.invokeSuper(o, args);
                return obj;
            }
        });
        emailProxy.sendEmail("hello");
    }
}

它的写法与JDK提供的方式类似,通过Enhancer类的create()方法即可增强一个对象,并传入对象的Class对象和一个MethodInterceptor接口的实现类,并在intercept()方法中对原方法进行增强。

总结

到此这篇关于Java实现动态代理的文章就介绍到这了,更多相关Java实现动态代理内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Java实现动态代理的实例代码

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Java动态代理与静态代理实例分析

这篇文章主要介绍了Java动态代理与静态代理实例分析的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Java动态代理与静态代理实例分析文章都会有所收获,下面我们一起来看看吧。一、静态代理静态代理的使用静态代理,代
2023-07-02

Android 动态菜单实现实例代码

Android 动态菜单 先上效果图比较简单,主要就是属性动画的使用和坐标角度的小细节。 实现 实现效果: 图标按照路径一路缩放渐变过来即可。 核心代码/*** Item开启动画** @param btnItem* @param inde
2022-06-06

java 多态实例代码

多态是同一个行为具有多个不同表现形式或形态的能力。多态就是同一个接口,使用不同的实例而执行不同操作。多态性是对象多种表现形式的体现,比如:在现实中,我们按下F1键这个动作:如果当前在Flash界面下弹出的就是AS 3的帮助文档如果当前在Wo
2023-05-30

java动态代理的实现方法

这篇文章主要介绍“java动态代理的实现方法”,在日常操作中,相信很多人在java动态代理的实现方法问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”java动态代理的实现方法”的疑惑有所帮助!接下来,请跟着小编
2023-06-20

Java动态代理如何实现

本篇内容介绍了“Java动态代理如何实现”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!JDK动态代理:利用反射机制生成一个实现代理接口的匿名
2023-06-30

Java注解实现动态数据源切换的实例代码

当一个项目中有多个数据源(也可以是主从库)的时候,我们可以利用注解在mapper接口上标注数据源,从而来实现多个数据源在运行时的动态切换。实现原理在Spring 2.0.1中引入了AbstractRoutingDataSource, 该类充
2023-05-31

Java动态代理机制的实例详解

Java动态代理机制在学习spring的时候,我们知道Spring主要有两大思想,一个是IoC,另一个就是AOP,对于IoC,依赖注入就不用多说了,而对于Spring的核心AOP来说,我们不但要知道怎么通过AOP来满足的我们的功能,我们更
2023-05-31

使用Java怎么实现静态代理和动态代理

本篇文章为大家展示了使用Java怎么实现静态代理和动态代理,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。代理模式代理模式(Proxy):为其他对象提供一个代理以控制对这个对象的访问。主要解决:在直接
2023-06-14

Java如何实现JDK动态代理

这篇文章主要讲解了“Java如何实现JDK动态代理”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Java如何实现JDK动态代理”吧!概念代理:为控制A对象,而创建出新B对象,由B对象代替执行
2023-07-02

java proxy动态代理怎么实现

在Java中,可以通过使用`java.lang.reflect.Proxy`类来实现动态代理。首先,需要定义一个接口,代表被代理类和代理类都需要实现的方法。```javapublic interface Subject {void doSo
2023-09-09

Java中怎么实现动态代理

今天就跟大家聊聊有关Java中怎么实现动态代理,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。一、概述 代理是一种设计模式,其目的是为其他对象提供一个代理以控制对某个对象的访问,代理类
2023-06-17

动态代理模拟实现aop的示例

AOP实现起来代码相当简单.主要核心是动态代理和反射.一.接口类:public interface MethodDao { public void sayHello(); }
2023-05-30

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录