Spring中的Jdk动态代理与Cglib动态代理
文章摘要
AOP动态代理包括JDK代理和Cglib代理。JDK代理基于接口使用反射,Cglib代理基于类生成子类。区别:JDK需接口,Cglib不需;Cglib目标类不能为final。
### 前言 在前面的spring中,提到了aop的原理就是使用了动态代理,这篇文章就写一下jdk代理和cglib代理。 先在这里贴一下相关的需要代理的对象和接口。 首先是接口: ```java public interface TestDao { void test(); } 复制代码 ``` 然后是实现类: ```java public class TestDaoImpl implements TestDao { @Override public void test() { System.out.println("test dao impl"); } } 复制代码 ``` ### 1.JdkProxy jdk动态代理:JDK动态代理只能对实现了接口的类生成代理; Jdk动态代理是利用了反射机制,在调用具体方法前或后,调用InvokeHandle来处理。 下面来实现一个具体的Jdk动态代理,首先写一个类实现InvokeHandle,并实现它的invoke()方法 ![JdkProxy.png](https://oss.120120.top/blog/2024/01/09/22690bccd30f4c969382ec7b82090995.png) JdkProxy的构造方法参数为一个泛型的Object,接下来就可以利用反射机制创建一个Jdk动态代理的工厂类: ![JdkFactory.png](https://oss.120120.top/blog/2024/01/09/bb31b8a53c474c75bc131989ab6c390e.png) 接下来写一个测试类,测试上面代码: ```java public static void main(String[] args) { TestDao jdkDao = JdkDynamicObjectFactory.getProxiedObject(TestDaoImpl.class); jdkDao.test(); } 复制代码 ``` 运行测试代码,可以看到控制台输出: ```java jdk dynamic before... test dao impl jdk dynamic after... 复制代码 ``` 以上就实现了Jdk动态代理,并对目标对象实现了增强。 ### 2.CglibProxy cglib动态代理:cglib是针对类实现代理,主要是对指定的类生成一个子类,覆盖其中的方法。 我们用Spring中 Enhancer 的方式来写一个CglibProxy: ![cglibProxy.png](https://oss.120120.top/blog/2024/01/09/c22c133d05774a6ea656a49938fc33f0.png) 然后同样写一个代理工厂类,参数为一个Class: ![cglibFactory.png](https://oss.120120.top/blog/2024/01/09/a5f12ebab8cb4856a6c0251b0658aa05.png) 同样的,写一个测试类,测试一下cglib动态代理: ```java public static void main(String[] args) { TestDao cglibDao = CglibObjectFactory.getProxiedObject(TestDaoImpl.class); cglibDao.test(); } 复制代码 ``` 运行测试代码,控制台输出如下: ```java cglib before... test dao impl cglib after... 复制代码 ``` 以上就实现了cglib动态代理,并对目标对象实现了增强。 ### 3.总结 a.jdk代理只能对实现了接口的类进行代理,而cglib代理可以对普通类进行代理; b.jdk代理是通过反射的方式来实现动态代理,而cglib则是通过为目标类生成一个子类的方式来实现动态代理; c.由于cglib代理是为目标类生成了一个子类,并对父类方法进行增强,所以目标类不能用final修饰; 作者:山主 链接:https://juejin.cn/post/7007323557759811592 来源:掘金 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
作者头像
admin
分享技术与生活
打赏作者

评论

暂无评论,快来抢沙发吧~