博客
关于我
Java反射机制剖析(三)-简单谈谈动态代理
阅读量:794 次
发布时间:2023-01-28

本文共 3839 字,大约阅读时间需要 12 分钟。

替换技术内容

通过学习反射机制,我们对反射有了基本的理解。本文将基于动态代理的例子,进一步深入探讨反射机制。

代理模式

代理模式是一种为其他对象提供代理的方法,以控制对目标对象的访问。这种模式通过引入间接性,实现对目标对象的访问控制。代理模式的主要特点是:代理类与委托类(目标对象)具有相同的接口,代理类负责预处理、过滤、转发消息,以及事后处理。通常情况下,一个代理类对象与一个委托类对象产生关联,代理类并未实现实际的业务逻辑,而是通过调用委托类的方法来提供特定服务。

代理模式分类

根据创建时间可以将代理分为静态代理和动态代理两种类型。

  • 静态代理:在程序设计完成后,由程序员手动编写源代码,并经过编译生成.class文件。应用程序在运行前已存在代理类文件。

  • 动态代理:动态代理类通常在程序运行时,由反射机制动态生成。这种方式的灵活性更高,可以更好地适应动态需求。

静态代理和动态代理的对比示例

静态代理示例:

// 业务接口类interface UserManager {    void addUser(String userId, String userName);    void delUser(String userId);    String findUser(String userId);    void modifyUser(String userId, String userName);}// 业务接口实现类class UserManagerImpl implements UserManager {    public void addUser(String userId, String userName) {        try {            System.out.println("UserManagerImpl.addUser() userId--->" + userId);            System.out.println("success--->addUser()");        } catch (Exception e) {            System.out.println("error--->addUser()" + e.getMessage());            throw new RuntimeException(e);        }    }    // 其他方法同理    public void delUser(String userId) {        System.out.println("UserManagerImpl.delUser() userId--->" + userId);    }    public String findUser(String userId) {        System.out.println("UserManagerImpl.findUser() userId--->" + userId);        return "张三";    }    public void modifyUser(String userId, String userName) {        System.out.println("UserManagerImpl.modifyUser() userId--->" + userId);    }}// 代理类class UserManagerImplProxy implements UserManager {    private UserManager userManager;    public UserManagerImplProxy(UserManager userManager) {        this.userManager = userManager;    }    public void addUser(String userId, String userName) {        try {            System.out.println("UserManagerImplProxy.addUser() userId--->" + userId);            userManager.addUser(userId, userName);            System.out.println("success--->addUser()");        } catch (Exception e) {            System.out.println("error--->addUser()" + e.getMessage());            throw new RuntimeException(e);        }    }    // 其他方法同理(空实现 [])}// 客户端类class Client {    public static void main(String[] args) {        UserManager userManager = new UserManagerImplProxy(new UserManagerImpl());        userManager.addUser("0001", "张三");    }}// 运行结果// start->addUser() userId->0001// UserManagerImpl.addUser() userId->0001// success->addUser()

动态代理示例:

// 业务接口类interface UserManager {    String test(String userId);}// 业务接口实现类class UserManagerImpl implements UserManager {    public String test(String userId) {        System.out.println("UserManagerImpl.test() userId--->" + userId);        return "张三";    }}// BusinessHandler类(动态代理)class BusinessHandler implements InvocationHandler {    private Object targetObject;    public BusinessHandler() {        this.targetObject = new UserManagerImpl();    }    public Object newProxyInstance() {        return Proxy.newProxyInstance(            targetObject.getClass().getClassLoader(),            targetObject.getClass().getInterfaces(),            this        );    }    public Object invoke(Method method, Object[] args) throws Throwable {        System.out.println("start->" + method.getName() + " userId->" + Arrays.toString(args));        Object ret = method.invoke(targetObject, args);        System.out.println("success->" + method.getName());        return ret;    }}// 客户端类class Client {    public static void main(String[] args) {        BusinessHandler handler = new BusinessHandler();        UserManager userManager = (UserManager) handler.newProxyInstance();        String name = userManager.test("0001");        System.out.println("Client.main() --- " + name);    }}// 运行结果// start->test 0001// test->start->test 0001// success->test Client.main() --- 张三

通过这两个示例可以看出,静态代理和动态代理在结构和实现方式上有显著区别。静态代理通过手动编写代理类到实现,较为复杂,而动态代理则利用反射机制动态生成代理类代码,更为灵活和高效。

转载地址:http://ciryk.baihongyu.com/

你可能感兴趣的文章
Elasticsearch7.3.1启动指定JDK11
查看>>
Elasticsearch下载安装
查看>>
Elasticsearch入门教程(Elasticsearch7,linux)
查看>>
elasticsearch的helpers.bulk和es_client.bulk的用法
查看>>
ElasticSearch设置字段的keyword属性
查看>>
Elasticsearch设置账号密码
查看>>
elasticsearch配置文件里的一些坑 [Failed to load settings from [elasticsearch.yml]]
查看>>
Elasticsearch面试题
查看>>
element ui 时间日期选择器 el-date-picker 报错 Prop being mutated “placement“
查看>>
Hibernate二级缓存配置
查看>>
element 如何使用自定义icon图标
查看>>
element-plus修改主题颜色
查看>>
element-plus的el-date-picker日期范围选择控件,根据开始日期限定结束日期的可选范围为开始日期到开始日期+30天
查看>>
18 个一线工作中常用 Shell 脚本【实用版】
查看>>
element-ui:el-input输入数字-整数和小数
查看>>
ElementUI-el-progress改变进度条颜色跟文字样式
查看>>
element事件(change,click)不触发
查看>>
ELK原理与介绍(转)
查看>>
ELK学习笔记(三)单台服务器多节点部署
查看>>
ELK应用日志收集实战
查看>>