当前位置: 首页高频题加分模版训练问题详情 【Java基础专题】14. 什么是动态代理?有什么用?Java中可以怎么样实现动态代理? 本问题对应的项目链接:高频题回答模版训练 回答指导:不用你写代码实现动态代理哈,只需要简单说明即可。
共以下 7 个回答
动态代理就是说在程序的运行期间,动态的给你的对象生成一个代理对象。区别于静态代理,它就是不需要你手动的写动态代理类。
动态代理的作用就是为了增强原本的方法的某一些功能。因为在实际的企业开发中,其实有很多逻辑它都是相似相同的,这就有可能会导致我们会写大量重复的代码。使用了动态代理之后,我们就可以将这些大量的重复逻辑提取出来。提取到动态代理的代理逻辑当中。就比如说spring中的日志管理和事务管理,它是具有通用的逻辑的。我们就可以把它使用动态代理的模式进行动态增强,而不需要我们每次写一个类都去写一写事物相关或者说日志相关的代码。使用的时候只需要简单的添加一个注解就可以了。
JAVA中实现动态代理主要有两种方式,第一种就是通过Proxy这个类它的newProxy instance这个方法。传入被代理类的内加载器。可能的返回类型。还有就是一个invocationhandler的实现,来拦截某一个具体的方法,在它的调用前后写上你的增强逻辑。实现动态代理。这个方法有一个前提就是需要你的背袋里的类,它需要实现一个借口。这个接口中需要声明你想要被代理的方法,通过这样的方式使你的代理内能够拥有被代理想要被代理的方法。第二种实现动态代理的方式就是通过cglib,他的底层逻辑就是使用了asm自解码处理框架,通过修改字解码的方式生成一个被代理类的子类来实现逻辑的增强。它相比于jDK自己的动态代理实现。有一个优点就是它可以不用使这个背带里类去实现某个接口。嗯,但是他也有他的缺点,在对于一些final修饰的方法他无法做到动态代理。
区别于静态代理,不是必须要实现接口并创建代理类,可以运行时动态扩展类的功能,Spring AOP权限控制、事务、日志等功能;
JDK动态代理 和 Cglib动态代理;
动态代理意思是,在运行时对特定的对象,在指定的方法前后执行增强逻辑,这样可以把公共部分的代码抽取出来,让每个模块的代码更加专注于自己业务的实现,比如:日志、事务管理、权限管理,这些代码可以抽取出来,在需要的时候,使用动态代理,执行这些增强逻辑。
具体的实现,例如Spring的aop,有两种动态代理的方式,分别为jdkProxy和cglib。
jdkProxy是基于InvocationHandler进行拦截,在目标对象的方法前后执行指定的增强逻辑,它要求对象的类一定要实现接口;
cglib是基于字节码的技术实现的,它通过继承目标对象的方式,重写父类的方法,在原有方法的基础上,执行增强逻辑,也因为要重写这些方法,所以cglib占用的JVM内存会比JdkProxy多一点,但是cglib不要求对象的类一定要实现接口,springBoot的AOP默认也是使用cglib
在运行时动态生成代理类对象,对原有功能进行增强和拓展,增强程序拓展性和灵活性。
aop就是基于jdk提供的动态代理和cglib实现的,可以通过aop实现日志记录,安全管理,性能统计。
可以使用jdk自带的reflect包中的Proxy类和invocationHandler接口生成动态代理类,也可以使用第三方类库cglib实现动态代理。
动态代理是在程序运行时动态生成代理类,由代理类来控制对原始对象的访问
动态代理可以在不修改原对象的情况下,对原对象进行方法增强。主要应用在各种框架中,比如 Spring 中的 AOP:在运行时动态创建代理类,从而在要执行方法前后插入额外的逻辑实现日志记录,性能监控等等功能;servlet 中的 fliter 同样使用代理对类来对请求做一些预处理和后处理,比如验证请求,检查用户权限等等。
Java 中有两种方式实现动态代理:JDK 自带的的 reflect 包,或者第三方代码生成库 Cglib。具体的,JDK 使用 reflect 包下的 Proxy 类和 InvocationHandler 接口来实现动态生成代理类。但是前提是被代理类必须要实现某个接口。而 Cglib 底层是使用一个字节码处理框架 ASM 来转换字节码并生成某个代理类的子类,通过继承的方式来实现动态代理,所以也就不需要被代理类去实现某个接口,做到 “无侵入”。
动态代理分为接口型动态代理和实现类型动态代理。前者用proxy类实现,实现时代理类会将目标对象target作为属性,继承InvocationHandler和实现invoke方法,在invoke方法中,利用反射对代理类的方法进行增强,本质上是接口的方法实现。而cglib通过对代理类的继承,说明他可以增强代理类的所有方法。举例子就是spring的事务机制。
我的理解是动态代理,实际上就是在不改变原有代码的情况下对原有的方法增强。对于一些方法,他们可能需要一些统一的处理逻辑,例如打印日志,这时候我们就可以通过创建代理对象,来对原有方法进行功能上的加强。实现动态代理有两种方式,一种是通过jdk reflect包提供的proxy类实现,还有一种是通过cglib的enhancer实现。
对于jdk proxy它是面向接口的动态代理,也就是说只有一个类实现了接口,我们才能对它进行代理,本质上来说就是这个代理对象实现了被代理对象的接口,所以它只能增强接口中的方法,具体代码逻辑是通过重写invokationhandler的invoke方法,通过反射的方式对原有方法进行增强。
对于cglib的enhancer它是面向父类的动态代理,也就是说它代理一个对象就是通过继承被代理对象对原有方法增强,这就意味着它可以增强被代理对象的所有方法,并且由于反射机制的存在,可以获取到父类方法上的所有注解。
动态代理经常出现在框架中,例如mybatis通过面向接口的动态代理,对接口进行实现。在spring aop机制中,通过动态代理机制,对方法进行增强,aop中的前置通知,返回通知,异常通知等,都是通过在动态代理过程中,在相对原方法的不同位置执行对应逻辑而实现的。