java的代理机制(静态代理和动态代理)

一. 代理的概念

为某个对象提供一个代理,以控制对这个对象的访问。

代理类和委托类有共同的父类或父接口,这样在任何使用委托类对象的地方都可以用代理对象替代。代理类负责请求的预处理、

过滤、将请求分派给委托类处理、以及委托类执行完请求后的后续处理。

从图中可以看出,代理接口(Subject)、代理类(ProxySubject)、委托类(RealSubject)形成一个“品”字结构。

 

二. 代理的分类

根据代理类的生成时间不同可以将代理分为 静态代理 和 动态代理 两种。

静态代理

由程序员创建或工具生成代理类的源码,再编译代理类。所谓静态也就是在程序运行前该代理类的字节码文件就已经存在,代理类和委托类的关系在运行前就确定了。 

优点:

业务类只需要关注业务逻辑本身,保证了业务类的重用性,这是代理的共有优点。

缺点:

1. 代理对象的一个接口只服务于一种类型的对象,如果要代理的方法很多,势必要为每一种方法都进行代理,静态代理在程序规模稍大时就无法胜任了。 

2. 如果接口增加一个方法,除了所有实现类需要实现这个方法外,所有代理类也需要实现此方法。增加了代码维护的复杂度。 

静态代理--代码实现git路径:

https://github.com/jichunyang19931023/dailyDemo/tree/master/staticProxyModel

 

动态代理(Spring AOP的实现原理

动态代理是在程序运行时,运用反射机制动态创建而成。动态代理又分为两种实现方式:JDK 动态代理 和 CGlib 动态代理 

JDK动态代理

JDK动态代理的代理类字节码在创建时,需要实现业务实现类所实现的接口作为参数。如果业务实现类是没有实现接口而是直接定义业务方法的话,就无法使用JDK动态代理了。(JDK动态代理重要特点是代理接口) 并且,如果业务实现类中新增了接口中没有的方法,这些方法是无法被代理的(因为无法被调用)。

CGlib动态代理

对于没有接口的类,需要使用CGlib来实现动态代理。CGLib采用了非常底层的字节码技术,其原理是通过字节码技术为一个类创建子类,并在子类中采用方法拦截的技术拦截所有父类方法的调用,顺势织入横切逻辑。JDK动态代理与CGLib动态代理均是实现Spring AOP的基础。

JDK动态代理和CGlib动态代理--代码实现git路径:

https://github.com/jichunyang19931023/dailyDemo/tree/master/dynamicProxyModel

JDK和CGlib两种动态代理方式区别

1、java动态代理是利用反射机制生成一个实现代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理。而Cglib动态代理是利用asm开源包,对代理对象类的class文件加载进来,通过修改其字节码生成子类来处理。

2、JDK动态代理只能对实现了接口的类生成代理,而不能针对类;CGlib是针对类实现代理,主要是对指定的类生成一个子类,覆盖其中的方法,因为是继承,所以该类或方法最好不要声明成final。

3、CGlib一个目标类方法会生成两个代理方法,一个重写目标方法,并实现代理逻辑,还有一个直接调用目标类方法。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

盛夏温暖流年

可以赏个鸡腿吃嘛~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值