Java动态代理(JDK和Cglib)

动态代理

代理模式,是为其他对象提供一个代理来控制对某个真实对象的访问。代理类负责对调用的消息进行处理和转发,以及在委托类执行后的一些后续操作的处理。代理类似一个演员的经纪人,负责对所有的活动进行筛选和过滤,并且将消息转发给该演员,在演员演出后,负责做一些收尾工作。

动态代理,它在静态代理的基础上又迈进了一步。可以动态的创建代理,并且动态的处理对所代理方法的调用。动态代理则分为以下两种:
- 1、JDK动态代理:
- 基于接口进行代理 (必须实现接口)
- 2、Cglib动态代理:
- 基于继承进行代理 原理为继承要代理的类,并Override其中的方法实现代理

JDK动态代理

动态代理的使用方法如下:

  • 实现InvocationHandler完成自己的调用处理器
  • 通过Proxy.newProxyInstance()来创建动态代理,该方法需要的到三个参数,
    • 一个类加载器(可从已被加载的对象中获取)
    • 代理实现的接口列表
    • 以及InvocationHandler接口的一个实现,并传递给处理器一个实际对象。
  • 通过代理对象来调用请求

这样,外部的所有调用请求,就都会重定向到调用处理器,在经过处理器的调用,通过Method.invoke()转发给委托对象。这样就可以简单实现了对方法调用的拦截和过滤。

/**
 * 定义一个接口并实现
 */
interface Interface {
    void doSomething();
}

class Real implements Interface {
    public void doSomething(String arg) {
        Sytstem.out.println("dosomething  " + arg);
    }
}
import java.lang.reflect.*;

/**
 * 实现InvocationHandler接口
 * 完成自定义的调用处理器
 */
class MyProxyHandler implements InvocationHandler {
    //被代理对象
    private Object proxied;
    public MyProxyHandler(Object proxied) {
        this.proxied = proxied;
    }

    public Object invoke(Object object, Method method, Object[] args)
    throws Throwable {
        System.out.println("****before:" + method + "****");
        method.invoke(proxied, args);
        System.out.println("****after:" + method + "****");
    }
}

/**
 * 通过Proxy.newProxyInstance()方法获取动态代理
 * 使用代理调用方法
 */
class DynamicProxy {
    public static void main(String[] args) {
        Real real = new Real();
        Interface proxy = (Interface)Proxy.newProxyInstance(
          Interface.class.getClassLoader(),
          new Class[]{ Interface.class },
          new MyProxyHandler(real);
        )
        proxy.doSomething("hello");
    }
}

Cglib动态代理

Chlib动态代理使用主要有如下几点:

  • 实现MethodInterceptor,完成拦截的切面处理
    • 通过methodProxy.invokeSuper(obj, args);来调用被代理的方法
  • 通过实例化的Enhancer生成代理对象,实例化步骤如下:
    • 实例化Enhancer:Enhancer enhancer = new Enhancer();
    • 设置被代理的基类:enhancer.setSuperClass(clz);
    • 设置回调函数,即是实现的切面:enhancer.setCallback(methodInterceptor);
    • 创建代理对象:enhancer.create();
  • 使用生成的代理对象完成调用
public class MyInterceptor implements MethodInterceptor {
    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        System.out.println("#####before######");
        Object result = null;
        try {
            result = methodProxy.invokeSuper(o, objects);
        } catch (Throwable e) {
            System.out.println(e.getMessage());
            throw e;
        }
        System.out.println("#####after#####");
        return result;
    }

    public static void main(String[] args) {
        BaseObject proxyObj = (BaseObject)getProxyObj(RealObject.class, new MyInterceptor());
        proxyObj.method();
    }

    public static Object getProxyObj (Class clz, MethodInterceptor callback) {
        Enhancer enhancer = new Enhancer();
        return enhancer.create(clz, callback);
    }
}

abstract class BaseObject {
    public abstract void method();
}

class RealObject extends BaseObject {

    @Override
    public void method() {
        System.out.println("real obj was called!!!");
    }
}
原文地址:https://www.cnblogs.com/enhe/p/12141698.html