代理模式

简介

定义: 为其他对象提供一种代理以控制对这个对象的访问。

使用场景:

  • 延迟加载(虚拟代理)

  • 权限控制(保护代理)

  • 远程调用(远程代理)

  • Spring AOP

代理类型:

  • 静态代理

  • JDK动态代理

  • CGLIB代理

UML

代码示例

  1. 被代理的接口

public interface OrderService {
    void create(int id);
    void pay(int id);
}
public class OrderServiceImpl implements OrderService {

    @Override
    public void create(int id) {
        System.out.println("create order");
    }

    @Override
    public void pay(int id) {
        System.out.println("pay order");
    }
}
  1. 被代理的实体类

public class Order {
    public void create(int id) {
        System.out.println("create");
    }

    public void pay(int id) {
        System.out.println("pay");
    }
}
  1. 静态代理

public class OrderServiceProxy implements OrderService {

    //被代理的对象
    private OrderService orderService;

    public OrderServiceProxy(OrderService orderService) {
        this.orderService = orderService;
    }

    @Override
    public void create(int id) {
        before();
        orderService.create(id);
        after();
    }

    @Override
    public void pay(int id) {
        before();
        orderService.pay(id);
        after();
    }

    private void before() {
        System.out.println("before: " + new Date());
    }

    private void after() {
        System.out.println("after: " + new Date());
    }
}
  1. JDK动态代理

public class LogHandler implements InvocationHandler {

    //被代理的对象
    Object target;

    public LogHandler(Object target) {
        this.target = target;
    }

    /**
     * 反射对象
     * @param proxy 代理对象
     * @param method    代理的方法
     * @param args  方法入参
     * @return java.lang.Object  方法执行结果
     * @author dcx
     * @date 2023/6/21 10:15
     **/
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        before();
        Object result = method.invoke(target, args);
        after();
        return result;
    }

    private void before() {
        System.out.println("before: " + new Date());
    }

    private void after() {
        System.out.println("after: " + new Date());
    }
}
  1. CGLIB动态代理

public class LogInterceptor implements MethodInterceptor {

    /**
     * 对象执行拦截
     *
     * @param o           被代理的对象
     * @param method      拦截的方法
     * @param objects     参数列表
     * @param methodProxy 对方法的代理
     * @return java.lang.Object
     * @author dcx
     * @date 2023/6/21 11:00
     **/
    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        before();
        // 注意这里是调用 invokeSuper 而不是 invoke,否则死循环,methodProxy.invokesuper执行的是原始类的方法,method.invoke执行的是子类的方法
        Object result = methodProxy.invokeSuper(o, objects);
        after();
        return result;
    }

    private void before() {
        System.out.println("before: " + new Date());
    }

    private void after() {
        System.out.println("after: " + new Date());
    }
}
  1. 使用方式

public class Test {

    /**
     * 静态代理
     * @author dcx
     * @date 2023/6/21 10:57
     **/
    public static void staticProxy() {
        //生成被代理对象
        OrderService orderService = new OrderServiceImpl();
        //生成代理对象
        OrderServiceProxy orderServiceProxy = new OrderServiceProxy(orderService);
        //代理对象执行
        orderServiceProxy.create(1);
        orderServiceProxy.pay(1);
    }

    /**
     * jdk动态代理
     * @author dcx
     * @date 2023/6/21 10:57
     **/
    public static void jdkProxy(){
        //目标类
        OrderService orderService = new OrderServiceImpl();
        //获取类加载器
        ClassLoader classLoader = orderService.getClass().getClassLoader();
        //获取对象实现的接口类,OrderServiceImpl实现的是OrderService接口类
        Class<?>[] interfaces = orderService.getClass().getInterfaces();
        //创建代理处理器
        LogHandler logHandler = new LogHandler(orderService);
        //创建代理对象
        OrderService orderServiceProxy = (OrderService) Proxy.newProxyInstance(classLoader, interfaces, logHandler);
        //代理对象执行方法
        orderServiceProxy.create(1);
        orderServiceProxy.pay(1);
        //输出代理对象class文件
        ProxyUtils.generateClassFile(orderService.getClass(),"OrderServiceImpljdkProxy");
    }

    /**
     * cglib 动态代理,方法增强
     * @author dcx
     * @date 2023/6/21 10:58
     **/
    public static void cglibProxy(){
        //生成拦截处理器
        LogInterceptor logInterceptor = new LogInterceptor();
        //方法增强处理类
        Enhancer enhancer = new Enhancer();
        //设置超类
        enhancer.setSuperclass(Order.class);
        //设置回调时拦截增强
        enhancer.setCallback(logInterceptor);
        //创建增强类
        Order order = (Order) enhancer.create();
        order.create(1);
        order.pay(1);
    }


    public static void main(String[] args) {
//        staticProxy();
//        jdkProxy();
        cglibProxy();
    }
}

Last updated

Was this helpful?