java动态创建代理对象

本文详细介绍了Java中的动态代理模式,包括动态创建代理对象的过程及其实现方式。通过具体实例展示了如何利用Proxy类和InvocationHandler接口来增强被代理对象的功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

代理模式在开发过程中有着众多好处,现在我先给大家首先介绍什么是代理模式,以及java的中代理模式的使用,最后再看代理模式的概念作用等自然就会明白了

1.动态创建代理对象
》》》》》》代理模式的字面意思,就是代理一个类,即被代理对象,让代理对象可
以有代理对象的功能或同时能够加强这个功能的,当然他还有其他作用
package ceom.proxy.test;

//Proxy,相当于工具类,帮助我们创建代理对象
import java.lang.reflect.Proxy;

//下面三个分别是  Proxy.newProxyInstance的三个参数
//person 实现接口,即马上要被代理的对象
import com.proxy.demo1.Person;

//work 接口内 有两个方法  go  和 have 方法
import com.proxy.demo1.Work;

//PersonPorxy实现处理类invocationhandler
import com.proxy.demo1.PersonPorxy;

public class test {
    public static void main(String[] args) {
        Person person = new Person();
        person.go();
        person.have();

        System.out.println("===========================");

         Work proxyperson= (Work)Proxy.newProxyInstance(Work.class.getClassLoader(),new Class[]{Work.class},new PersonPorxy());

        proxyperson.go();
        proxyperson.have();
    }
}
  • newProxyInstance的参数说明
    第一个参数:要被代理对象的加载器
    第二个参数:被代理对象实现的接口的.class,必须是数组结构(原因是一个被代理对象即类 可以实现多个接口类)
    第三个参数:实现InvocationHandler接口的一个类(这是干嘛的呢?可能很多人不理解,可是你想想,Proxy.newProxyInstance 返回的就是一个 代理对象 ,他实现了被代理对象person的work接口 ,同时加强了person类的方法,那么如何加强person方法的方法呢?请看下面的PersonPorxy类吧)
package com.proxy.demo1;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

public class PersonPorxy implements InvocationHandler{
    Person person=new Person();




	 /**
     * Proxy.newProxyInstance创造出的代理对象
     * 执行接口里的方法都会执行invoke,
     * @param proxy		这个参数是代理对象方法,暂放有时间再研究,
     * 					不过这不需要里用不到
     * @param method	被代理对象的方法,照着this理解,被代理对象
     * 					使用哪个方法,method就是谁
     * @param args		被代理对象方法的参数
     * @return			返回被代理对象的方法执行后的返回值
     * @throws Throwable
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

//        //1.获取方法名
//        String methodName = method.getName();
//        //2.获取方法所在的类的名称
//        String className = method.getDeclaringClass().getName();
//        //3.组合key
//        String key=className+"."+methodName;
        //4.diao
        System.out.println("                                    ");
        
        System.out.println("方法名字:"+method.getName()+";\n"+"class全限定类名:"+method.getDeclaringClass().getName());

		Object obj=null;
		
		//从这你应该可以知道 
		//可以通过method.getName获取的方法名的不同
		//来有针对性的来强化代理方法,
        if (method.getName()=="go"){
            System.out.println("这是高级的人");
             obj= method.invoke(person, args);
            System.out.println("开车上班");

            return obj ;
        }
        //返回的method.invoke就是 test类里的method方法 go() 和have()
        obj = method.invoke(person, args);
        System.out.println("                                    ");
        return obj;
    }
}

输出结果

在这里插入图片描述

下面贴出用到的Person和work类

Person类
package com.proxy.demo1;

public class Person implements Work {


    public void go() {
        System.out.println("走路上班");
    }

    public void have() {
        System.out.println("吃米饭");
    }
}
Work
package com.proxy.demo1;

public interface Work {
    public void go();
    public void have();
}

下面是硬概念,再看一下吧

代理模式:

作用:

为其他对象提供一种代理以控制对这个对象的访问。

在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介作用。

其特征是代理与委托类有同样的接口。

代理模式是常用的设计模式。

功能:

代理类不仅仅是一个隔离客户端和委托类的中介。

我们还可以借助代理类再次增加一些功能,而不需要修改原有代码。符合开闭原则。

代理类主要为委托类处理消息、过滤消息、把消息转发给委托类、以及事后处理工作。

代理类与委托类之间会存在关联关系,一个代理类的对象与一个委托类的对相关联。

代理类的对象本身并不实现服务,而是通过委托类的对象的方法来提供特定的服务。

其实:就是真正的业务功能还是由委托类来实现,但是在实现业务之前的一些公共服务,例如在项目开发中忘记了加入缓冲、日志等的功能。后期想加入,就可以使用代理来实现而没有必要打开已经封装好的委托类。

分类:

代理可以分为两种:静态代理、动态代理。(我上面的是动态创建)

### U-Boot 设备模型 (dm) 驱动文档和实例 #### 理解 U-Boot 的设备模型框架 U-Boot 中引入了设备模型(Device Model, DM),旨在提供种统的方式来管理和配置硬件资源。DM 提供了种抽象层,使得不同类型的设备可以被致地处理[^1]。 #### 初始化过程中的角色 当 U-Boot 进入其主要执行阶段时,会经历系列复杂的初始化操作,在此期间设备模型扮演着重要角色。特别是对于那些需要早期启动支持的组件来说,DM 能够确保这些外设得到恰当设置并准备就绪[^2]。 #### 编写自定义驱动程序指南 为了创建个新的基于 DM 架构下的驱动模块,开发者应当遵循如下原则: - **注册新平台数据结构**:通过 `uclass_driver` 结构体来描述特定类别的通用行为; - **实现 probe 函数**:这是每个具体设备都必需提供的入口点之;它负责完成实际硬件资源配置工作以及任何必要的软件状态初始化。 - **利用宏简化开发**:如 `DECLARE_GLOBAL_DATA_PTR` 可帮助访问全局变量而无需显式传递指针参数。 下面给出段简单的 LED 控制器驱动代码片段作为例子: ```c // drivers/led/uclass.c static int led_bind(struct udevice *dev) { printf("Binding %s\n", dev->name); return 0; } static const struct udevice_id led_ids[] = { { .compatible = "example-led" }, { } }; U_BOOT_DRIVER(led_example) = { .name = "led_example", .id = UCLASS_LED, .of_match = led_ids, .bind = led_bind, }; ``` 上述代码展示了如何声明个名为 `"led_example"` 的驱动,并将其绑定到兼容字符串为 `"example-led"` 的节点上。这里还实现了基本的日志输出功能用于调试目的。 #### 使用命令行接口测试驱动 旦完成了驱动编写之后,则可以通过 U-Boot 命令提示符来进行交互式的验证。例如,假设已经加载了个 SPI NOR Flash 存储芯片的支持库,则可通过输入相应指令查看当前连接情况或者读取指定地址处的数据内容。 ```shell => sf probe 0 # 探测第零号SPI flash设备 SF: Detected w25q80bv with page size 256 Bytes, erase size 4 KiB, total 1 MiB. ``` 以上命令将会尝试识别编号为 0 的 SPI NOR Flash 并打印出检测结果摘要信息。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值