代理模式
代理模式是面向对象编程中比较常见的设计模式。

静态代理
优点:可以在不修改被代理类源码的基础上可以对被代理类中的方法进行附加和增强,前提是被代理类和代理类必须实现同一个接口或者继承同一个类
缺点:静态代理只可以对一个主题接口进行代理,如果主题接口不同即使方法相同,也是需要创建两个代理类
由此可见我们需要为每一个服务创建一个代理类,工作量太大,不易管理,同时接口一旦发生变化,则代理类也需要发生变化
代理类无法访问被代理类独特的方法,但是一个代理类可以代理同个主题接口下的多个实现类
所有的代理类每次只可以代理同一个主题接口的实现类
代码示例:
// 放电影的接口 也就是一个主题接口
public interface Movie {
/**
* 放电影
*/
void play();
}
//实现类
public class RealMovie implements Movie {
@Override
public void play() {
System.out.println("您正在观看的是:阿丽塔战斗天使");
}
}
//代理类
public class Cinema implements Movie{
Movie movie;
public Cinema(Movie movie) {
this.movie = movie;
}
@Override
public void play() {
System.out.println("啤酒饮料矿泉水");
movie.play();
System.out.println("小伙子收收脚");
}
}
//测试类
public class ProxyTest {
public static void main(String[] args) {
RealMovie realMovie = new RealMovie();
RealMovie2 realMovie2 = new RealMovie2();
Cinema cinema = new Cinema(realMovie2);
cinema.play();
}
}
动态代理 JDK
优点:
动态代理是可以动态生成代理类,代理逻辑和业务逻辑是分开的,低耦合
动态代理可以代理不同主题的实现类,只要他们的代理工作内容是一致的
是JDK原生动态代理,不需要外部依赖,运行较快
缺点:
只可以基于接口进行代理
因为Java是单继承的,而代理类又必须继承自Proxy类,所以jdk代理是必须基于接口的代理方式.
步骤:
(1)主题接口
(2)被代理类
(3)动态代理的代理工作处理器
要求必须实现:java.lang.reflect.InvocationHandler接口,重写
Object invoke(Object proxy, Method method,Object[] args)
(4)创建代理类对象
java.lang.reflect.Proxy类型的静态方法
newProxyInstance(ClassLoader loader, Class[] interfaces,InvocationHandler h )
(5)调用对用的方法

动态代理 cglib
优点:
基于类可以对类和接口实现动态代理,不像JDK动态代理一样局限于有接口的前提
动态代理可以代理不同主题的实现类,只要他们的代理工作内容是一致的
原理:CGLib动态代理是代理类去继承目标类,然后重写其中目标类的方法啊,这样也可以保证代理类拥有目标类的同名方法
缺点:
由于不是原生的,执行效率没有JDK块
AOP使用哪种动态代理?
- 当bean的是实现中存在接口或者是Proxy的子类,—jdk动态代理;不存在接口,spring会采用CGLIB来生成代理对象;
- JDK 动态代理主要涉及到 java.lang.reflect 包中的两个类:Proxy 和 InvocationHandler。
- Proxy 利用 InvocationHandler(定义横切逻辑) 接口动态创建 目标类的代理对象。
jdk动态代理
- 通过bind方法建立代理与真实对象关系,通过Proxy.newProxyInstance(target)生成代理对象
- 代理对象通过反射invoke方法实现调用真实对象的方法
动态代理与静态代理区别
- 静态代理,程序运行前代理类的.class文件就存在了;
- 动态代理:在程序运行时利用反射动态创建代理对象
CGLIB与JDK动态代理区别
- Jdk必须提供接口才能使用
- CGLIB不需要,只要一个非抽象类就能实现动态代理
- jbk动态代理是jdk自带的,不用导入其他的依赖,运行效率较快
- CGLIB 是需要导入第三方的依赖,运行效率没有jdk动态代理快,但是不用基于接口
jdk和cglib两种代理方式的选择
首先明确在创建代理实现类时, jdk的速度要高于cglib,所以选择的时候:
当代理类有接口的时候,选择JDK动态代理,因为效率比较高
当代理类没有接口的时候,选择cglib代理,因为JDK无法代理实现类没有接口的情况


1428

被折叠的 条评论
为什么被折叠?



