一、类型
结构型设计模式
二、代理模式的定义
代理模式 是指为其他对象提供一种代理, 以控制对这个对象的访问.
代理对象在客户端和目标对象之间起到中介作用.
三、静态代理和动态代理区别
静态代理: 硬编码、手动注入, 手动拿到目标对象的引用, 手动调用代理目标的方法.
动态代理: 具有更强的扩展性, 自动注入, 自动生成一个新的类(同一个继承体系)
特征:
1.拿到代理目标对象的引用
2.实现功能增强
3.保护目标对象
四、动态代理对象的创建过程
- 动态拼接出代理对象的java类的代码(包括java类的import xxx、类名、构造方法、继承接口、方法等动态拼接出来形成一个正常的java类)
- 用文件流将代理对象的java类输出到磁盘, 保存为$Proxy0.java文件
- 将$Proxy0.java文件进行编译成.class文件, 新文件为$Proxy0.class
- 将生成的$Proxy0.class加载到JVM内存中
- 返回新的代理对象
五、CgLib Proxy 与 JDK Proxy 区别
不同点:
- CgLib Proxy 使用继承的方式, 覆盖父类的方法.
- JDK Proxy 采用实现接口的方式, 必须要求代理的目标实现一个接口.
- CgLib Proxy 对目标类没有任何要求.
- JDK Proxy 对于用户而言, 依赖更强, 调用更复杂.
- CgLib Proxy 采用另外一套API, 没有使用反射, 性能更高.
- JDK Proxy 生成逻辑较为简单, 执行效率相对较低, 每次都使用到反射.
相同点:
- 都是通过生成字节码, 重组成一个新的类.
CgLib 有个坑:
- 由于使用的继承, 目标代理类不能有final修饰的方法, 他会忽略final修饰的方法.
六、代理模式优点
- 代理模式能将代理对象与真实被调用的目标对象分离.
- 一定程度上降低了系统的耦合度, 易于扩展.
- 代理可以起到保护目标对象的作用.
- 增强目标对象.
七、代理模式缺点
- 代理模式会造成系统设计中类数量增加.
- 在客户端和目标对象之前增加了一个代理对象, 会降低请求速度.
- 增加系统复杂度
八、Spring 中的代理选择原则
- 当 Bean 有实现接口时, Spring 就会使用 JDK 的动态代理.
- 当 Bean 没有实现接口时, Spring 会选择 CGLib.
Spring 可以通过配置强制使用 CGLib, 只需在 Spring 配置文件中加入以下代码:
<aop:aspectj-autoproxy proxy-target-class='true'/>
九、JDK 动态代理的使用
public class MyProxy implements InvocationHandler {
// 目标对象接口
private IPerson target;
public IPerson getInstance(IPerson target){
this.target = target;
Class<? extends IPerson> clazz = target.getClass();
return (IPerson) Proxy.newProxyInstance(clazz.getClassLoader(), clazz.getInterfaces(),this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
before();
Object invoke = method.invoke(this.target, args);
after();
return invoke;
}
private void before(){
System.out.println("before()...");
}
private void after(){
System.out.println("after()...");
}
}
public static void main(String[] args){
MyProxy proxy = new MyProxy();
IPerson instance = proxy.getInstance(new Zhangsan());
instance.doSomething();
}
执行结果
----------------------------------------------------------------------------------
before()...
张三正在执行某件事...
after()...
----------------------------------------------------------------------------------