JAVA 代理模式

System.out.println(“具体操作====”);

System.out.println(“被代理类执行完毕====”);

}

}

复制代码

三、创建一个对应的代理类,同样实现代理接口,重写接口中的方法,在类中定义一个Object类,用来获取到被代理类的对象,然后执行被代理对象的方法+自己另外的功能方法

//代理类

class ProxyObject implements Object1{

Object1 obj;

public ProxyObject() {

System.out.println(“代理类创建成功”);

obj = new ObjectImpl();

}

@Override

public void action() {

System.out.println(“代理类开始执行”);

obj.action();

}

}

复制代码

image.png

其实这时候我们也发现一个问题,那就是代码很不灵活,我们需要在编译前就想好哪写类需要用到代理模式并且给它们写好对应的代理类,这样未免也太麻烦了! 那么这时候基于反射原理动态代理就有用武之地!

二、动态代理


前面说到,动态代理基于的是java反射原理,那么具体怎么用到的呢? 其实就是我们在原来被代理类和代理类一对一的关系把它简化成了被代理类和代理类多对一的关系,我们只需要创建一个动态代理类,实现InvocationHandler接口,然后通过动态获取传入的被代理的对象,并动态执行代理对象的方法。这样听起来好像有点绕,那么我们根据代码来具体看一看:

定义动态代理模式的步骤

一、创建代理接口,也就是被代理方所需要实现的最基本的功能(这里为了体现动态代理的功能所以定义了两个不同的代理)

//动态代理的接口1

interface Subject{

void action();

}

//动态代理的接口2

interface ClothFactory{

void test();

}

复制代码

二、创建被代理类,实现代理接口,重写接口中的方法。

//被代理类1

class RealSubject implements Subject{

@Override

public void action() {

System.out.println(“我是被代理类!!!!!!!”);

}

}

//被代理类2

class NikeclothFactory implements ClothFactory{

@Override

public void test() {

System.out.println(“Nike工厂正在加工衣服…”);

}

}

复制代码

三、创建动态代理类

class MyInvocationHandler implements InvocationHandler{

Object obj;//实现了接口的被代理类的对象的声明

//1、给被代理的对象实例化 2、返回一个被代理类的对象

public Object blind(Object obj){

this.obj = obj;

return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(),this);

}

//当通过代理类的对象发起对被重写的方法的调用时,会自动转化成对如下的invoke方法的调用

@Override

public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

//method方法的返回值是returnVal

Object returnVal = method.invoke(obj,args);

return returnVal;

}

}

复制代码

因为这部分是动态代理的关键所以对代码进行解释;

在定义动态代理类的时候分几个步骤:

1、定义一个实现了接口的被代理类的对象的声明,后面用于接收被代理类的对象。

2、定义blind方法,用于给被代理的对象实例化,并通过反射,返回一个被代理的对象。通过Proxy.newProxyInstance这个静态方法,分别传入三个值:

被代理对象的类加载器被调用对象实现的接口实现了InvocationHandler

其实也比较好理解,首先代理对象和被代理对象的类加载器是同一个,再加上被调用对象实现的接口,自然能够通过反射得到代理对象。

3、在实现InvocationHandler接口的时候我们被要求实现一个invoke方法,这也是核心,当通过代理类的对象发起对被重写的方法(接口中定义的方法)的调用时,会自动转化成对invoke 的调用。让我们看看invoke的参数列表的后面两个,methodargs,是不是特别眼熟!这不就是通过反射获取方法的参数么(不清楚的同学可以看看我的上一章讲反射),那么其实就是通过反射,实现对被代理类的对象的方法调用,返回一个Object类型作为返回值的承担者。

四、主函数调用测试

public class DongTai {

public static void main(String[] args) {

//1、创建被代理类的对象

RealSubject real = new RealSubject();

//2、创建一个实现了InvocationHandler接口的对象

MyInvocationHandler myInvocationHandler = new MyInvocationHandler();

//3、调用blind方法,动态的返回一个根据传入的real对象所实现的接口的代理类对象

Subject subject = (Subject) myInvocationHandler.blind(real); //此时的sub就是代理类的对象

subject.action(); //转到对InvacationHandler接口的实现类的invoke()方法的调用

//举例2:

NikeclothFactory nike = new NikeclothFactory();

ClothFactory factory = (ClothFactory) myInvocationHandler.blind(nike);

factory.test();

}

最后

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,不论你是刚入门Java开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!

如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,不论你是刚入门Java开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!

如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

  • 14
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值