JAVA动态代理详解

2022-07-24 14:37:45

JAVA动态代理详解

问题

1:什么是静态代理,动态代理?
2:动态代理的好处?

什么是静态代理

以生活中例子来看,我作为某某品牌面膜的北京区代理,我替厂家卖面膜,我属于代理,厂家属于委托方。
联系到JAVA中就是,我作为一个代理类,我替委托类去调用方法,同时可以添加一些附加的功能。
如果一个代理类在程序运行之前就已经存在了,那么这种代理方式被称为静态代理。
先上代码
父接口:

publicinterfacePerson{/**
     * 吃饭
     */voideat();/**
     * 拉稀
     */voidshit();}

委托类:

classZhangsanimplementsPerson{@Overridepublicvoideat(){System.out.println("我每天都会吃饭;");}@Overridepublicvoidshit(){System.out.println("我偶尔会拉稀;");}}

静态代理类:

classDynamicPersonimplementsPerson{/**
     * 委托类
     */privateZhangsan zhangsan;@Overridepublicvoideat(){System.out.println("附加功能");
        zhangsan.eat();}@Overridepublicvoidshit(){}}

由上代码可知,代理类中将委托类引入了进来,但是怎么保证代理类的方法列表和委托类的方法列表一致呢,这里是通过接口约束了方法列表。

静态代理的弊端:对于委托类的每一个方法,都得重新编辑同时加入自己的附加功能,委托类方法过多时,效率太低。

动态代理引入

动态代理的引入就是在静态代理的基础上,添加了一个中间处理类,当调用委托类的方法时,优先进入中间处理类,自定义的附加功能放在中间处理类中即可。
动态代理的优势在于可以很方便的对代理类的函数进行统一的处理,而不用修改每个代理类的函数。

中间处理类:

classHandleimplementsInvocationHandler{/**
     * 委托类
     */privateObject obj;/**
     * 构造方法
     * @param obj 委托类对象
     */publicHandle(Object obj){this.obj= obj;}@OverridepublicObjectinvoke(Object proxy,Method method,Object[] args)throwsThrowable{//自定义添加内容System.out.println("我每天先刷牙;");//调用委托类的方法Object result= method.invoke(obj, args);return result;}

测试类:

publicstaticvoidmain(String[] args){//获取中间处理类Handle handle=newHandle(newZhangsan());//获取动态代理实例 向上转型Person person=(Person)Proxy.newProxyInstance(Person.class.getClassLoader(),newClass[]{Person.class}, handle);

        person.shit();}

测试结果:

我每天先刷牙;
我偶尔会拉稀;Process finishedwithexit code0

注意点

方法内部调用方法的情况

classZhangsanimplementsPerson{@Overridepublicvoideat(){System.out.println("我每天都会吃饭;");}@Overridepublicvoidshit(){System.out.println("我偶尔会拉稀;");}@OverridepublicvoideatAndShit(){eat();shit();}}

输出结果:

我每天先刷牙;
我每天都会吃饭;
我偶尔会拉稀;Process finishedwithexit code0
对于委托类方法中的嵌套方法调用,是走方法内部调用,没有代理对象

动态代理分类

那么在Spirng当中动态代理有两种

  • 第一种是JDK自带的动态代理
    1.JDK动态代理是利用反射机制生成一个实现代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理. 需要指定一个类加载器,然后生成的代理对象实现类的接口或类的类型,接着处理额外功能. JDK是基于接口

  • 第二种是Cglib的动态代理
    2.Cglib是动态代理利用asm的开源包,对代理对象的Class文件加载进来,通过修改其字节码生成的子类来处理 Cglib是基于继承父类生成的代理类.

两种代理方式的区别:

  • 1:JDK动态代理制能对实现了接口的类生成代理,而不是针对类

  • 2:CGLIB是针对类实现代理,主要对指定的类生成一个子类,覆盖其中的方法,添加额外功能,因为是继承,所以该类方法不能用final来声明.

对于具体CHLIB的代码示例参考:
https://blog.csdn.net/qq_42807370/article/details/87354522

  • 作者:卟啉亮的小博客
  • 原文链接:https://blog.csdn.net/ll1037497262/article/details/122840917
    更新时间:2022-07-24 14:37:45