设计模式之代理模式异同

  1. 静态代理和动态代理的区别:

(1) 简单说,就是代理对象是否是动态生成的,静态代理不是,动态代理是。

(2) 详细说,考虑代理类的字节码的编译运行情况,考虑在程序运行前是否就已经存在代理类的字节码文件,静态代理是已经存在,动态代理不是,是等到程序运行时由jvm通过反射等机制动态生成的。

  1. 动态代理jdk 和 cglib 区别:

目标对象是否需要实现接口,jdk需要,cglib不需要。jdk代理的代理对象是利用反射机制动态生成,而cglib的代理对象是利用拦截机制动态生成。

  1. jdk代理基本介绍

  • 代理对象, 不需要实现接口,但是目标对象要实现接口,否则不能用动态代理

  • 代理对象的生成,是利用JDK的API(利用反射机制),动态的在内存中构建代理对象

  • JDK代理也叫做接口代理

  1. JDK中生成代理对象的API

  • 代理类所在包:java.lang.reflect.Proxy

  • JDK实现代理只需要使用newProxyInstance方法,但是该方法需要接收三个参数,

  1. jdk代理的代码

//jdk代理,代理工厂,生成代理对象
public class ProxyFactory {

 //维护一个目标对象 , Object
 private Object target;

 //构造器 , 对target 进行初始化
 public ProxyFactory(Object target) {
  
  this.target = target;
 } 
 
 //给目标对象 生成一个代理对象
 public Object getProxyInstance() {
  
  //说明
  /*
   *  public static Object newProxyInstance(ClassLoader loader,
                                          Class[] interfaces,
                                          InvocationHandler h)

            //1. ClassLoader loader : 指定当前目标对象使用的类加载器, 获取加载器的方法固定
            //2. Class[] interfaces: 目标对象实现的接口类型,使用泛型方法确认类型
            //3. InvocationHandler h : 事情处理,执行目标对象的方法时,会触发事情处理器方法, 会把当前执行的目标对象方法作为参数传入
   */
  return Proxy.newProxyInstance(target.getClass().getClassLoader(), 
    target.getClass().getInterfaces(), 
    new InvocationHandler() {
     
     @Override
     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
      // TODO Auto-generated method stub
      System.out.println("JDK代理开始~~");
      //反射机制调用目标对象的方法
      Object returnVal = method.invoke(target, args);
      System.out.println("JDK代理提交");
      return returnVal;
     }
    }); 
 }
 
}
  1. cglib代理基本介绍

Cglib代理也叫作子类代理,它是在内存中构建一个子类对象从而实现对目标对象功能扩展。

  1. 在AOP编程中如何选择代理模式:

(1) 目标对象需要实现接口,用JDK代理

(2) 目标对象不需要实现接口,用Cglib代理

  1. cglib 代理的代码

public class ProxyFactory implements MethodInterceptor {

 //维护一个目标对象
 private Object target;
 
 //构造器,传入一个被代理的对象
 public ProxyFactory(Object target) {
  this.target = target;
 }

 //返回一个代理对象:  是 target 对象的代理对象
 public Object getProxyInstance() {
  //1. 创建一个工具类
  Enhancer enhancer = new Enhancer();
  //2. 设置父类
  enhancer.setSuperclass(target.getClass());
  //3. 设置回调函数
  enhancer.setCallback(this);
  //4. 创建子类对象,即代理对象
  return enhancer.create();
  
 }
 

 //重写  intercept 方法,会调用目标对象的方法
 @Override
 public Object intercept(Object arg0, Method method, Object[] args, MethodProxy arg3) throws Throwable {
  // TODO Auto-generated method stub
  System.out.println("Cglib代理模式 ~~ 开始");
  Object returnVal = method.invoke(target, args);
  System.out.println("Cglib代理模式 ~~ 提交");
  return returnVal;
 }

}

你可能感兴趣的:(#代理模式,代理模式,设计模式,java)