代理设计模式 (静态代理设计模式)+ 动态代理(JDK和Cglib)

时间:2023-03-09 03:04:32
代理设计模式 (静态代理设计模式)+  动态代理(JDK和Cglib)

一、代理设计模式

1、设计模式:前人总结一套解决特定问题的代码

2、代理设计模式优点:

    2.1 保护真实对象

    2.2 让真实对象职责更明确

    2.3 扩展

3、代理设计模式

    3.1 真实对象(老总)

    3.2 代理对象(秘书)

    3.3 抽象对象(抽象功能),(谈小目标)

二、静态代理设计模式

1、由代理对象代理所有真实对象的功能

  1.1 自己编写代理类

  1.2 每个代理的功能需要单独编写

2、静态代理设计模式的缺点:

  2.1 当代理功能比较多时,代理类中方法需要写很多

三、动态代理

  1、为了解决静态代理频繁编写代理功能缺点

  2、分类:

    2.1、JDK提供的

    2.2、cglib 动态代理

四、JDK动态代理

  1、和 cglib动态代理对比

    1.1、 优点:jdk自带,不需要额外导入jar

    1.2、缺点:

      1.2.1 真实对象必须实现接口

      1.2.2 利用反射机制,效率不高

  2、基于反射实现动态代理

  实例:

public class Laozong implements Gongneng{
@Override
public void chifan() {
System.out.println(" 吃饭");
}
@Override
public void xiaomubiao() {
System.out.println(" 谈小目标");
}
}
public interface Gongneng {
void chifan();
void xiaomubiao();
}
public class Mishu implements InvocationHandler{
private Laozong laozong=new Laozong();
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
System.out.println("您有预约时候吗???");
Object result = method.invoke(laozong, args);
System.out.println("收集访客信息");
return result;
}
}
public class Women {
public static void main(String[] args) {
Mishu mishu=new Mishu();
//第一个参数:类加载器
//第二个参数:proxy需要实现什么接口
//第三个参数:通过接口对象调用方法时,需要调用哪个类的invoke方法
Gongneng gongneng = (Gongneng) Proxy.newProxyInstance(Women.class.getClassLoader(),new Class[]{Gongneng.class},mishu);
gongneng.chifan();
gongneng.xiaomubiao();
}
}

五、cglib动态代理

1、cglib优点:

  1.1 基于字节码,生成真实对象的子类

    1.1.1 运行效率高于JDK动态代理

  1.2 不需要实现接口

2、cglib缺点:

  2.1 非JDK功能,需要额外导入jar

3、使用spring aop时,只要出现Proxy 和真实对象转换异常:

  3.1、 设置为true 使用 cglib

  3.2、设置为false使用 jdk(默认值)

<aop:aspectj-autoproxy proxy-target-class="false"></aop:aspectj-autoproxy>

4、实例:

public class Laozong {
public void chifan(){
System.out.println("吃饭");
}
public void xiaomubiao(){
System.out.println("小目标");
}
}
public class Mishu implements MethodInterceptor{
@Override
public Object intercept(Object arg0, Method arg1, Object[] arg2,
MethodProxy arg3) throws Throwable {
System.out.println("预约时间");
Object result = arg3.invokeSuper(arg0, arg2);
System.out.println("收集信息");
return result;
}
}
public class Women {
public static void main(String[] args) {
Enhancer enhan=new Enhancer();
enhan.setSuperclass(Laozong.class);
enhan.setCallback(new Mishu()); Laozong laozong = (Laozong) enhan.create();
laozong.chifan();
laozong.xiaomubiao();
}
}