Skip to content

代理模式

代理(proxy),简单来说就是帮你去办事,他也是一种设计模式,可以代理某个对象来达到在不改变代码的情况下对对象进行扩展或增强,同时这也是spring两大核心AOP的核心

动态代理

spring动态代理有两个,一个是cglib动态代理,一个是jdk的动态代理

jdk动态代理

1643190408726

java.lang.reflect.Proxy:这是Java动态机制的主类,提供了一个静态方法来为一组接口的实现类动态地成成代理类及其对象

实例代码

接口:

java
public interface Car {
    // 开车方法
    void run();
}

实现类:

java
public class LuHu implements Car {
    // 重写功能方法
    @Override
    public void run() {
        System.out.println("开车");
    }
}

代理类:

java
public class LuHuProxy implements InvocationHandler {
    // 实例
    private final Car car;

    // 构造方法
    public LuHuProxy(Car car) {
        this.car = car;
    }

    // 创建代理对象
    public Car createProxy() {
        return (Car) Proxy.newProxyInstance(car.getClass().getClassLoader(), car.getClass().getInterfaces(), this);
    }

    // 动态代理
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("开车之前干的事情");
        Object invoke = method.invoke(car, args);
        System.out.println("开车之后干的事情");
        // 返回代理对象
        return invoke;
    }
}

测试:

java
// 创建代理对象
LuHuProxy luHuProxy = new LuHuProxy(new LuHu());
// 动态代理
Car proxy = luHuProxy.createProxy();
// 调用代理对象的方法
proxy.run();

要求:

1、配代理的类有父类的接口

2、代理类持有被代理类的实例

cglib动态代理

maven包:

xml
<dependency>
    <groupId>cglib</groupId>
    <artifactId>cglib-nodep</artifactId>
    <version>3.3.0</version>
</dependency>
实例代码

类:

java
public class Lu {
    public void run() {
        System.out.println("车开起来了");
    }

    public void stop() {
        System.out.println("车停下来了");
    }
}

代理类:

java
public class LuProxy implements MethodInterceptor {
    // 创建虚拟代理对象
    Enhancer enhancer = new Enhancer();

    // 创建代理对象
    public Object createProxy(Class clazz) {
        // 设置被代理对象
        enhancer.setSuperclass(clazz);
        // 设置回调
        enhancer.setCallback(this);
        // 创建虚拟的子类对象
        return enhancer.create();
    }

    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        // 判断方法名
        if (method.getName().equals("run")) {
            return run(o, objects, methodProxy);
        } else if (method.getName().equals("stop")) {
            return stop(o, objects, methodProxy);
        }

        return o;
    }

    public Object run(Object o, Object[] objects, MethodProxy methodProxy) throws Throwable {
        System.out.println("开车之前");
        // 执行父类方法
        Object o1 = methodProxy.invokeSuper(o, objects);
        System.out.println("开车之后");
        return o1;
    }

    public Object stop(Object o, Object[] objects, MethodProxy methodProxy) throws Throwable {
        System.out.println("停车之前");
        // 执行父类方法
        Object o1 = methodProxy.invokeSuper(o, objects);
        System.out.println("停车之后");
        return o1;
    }
}

测试:

java
Lu proxy = (Lu) new LuProxy().createProxy(Lu.class);
proxy.stop();

底层原理:帮你创建一个代理类的子类,子类默认拥有父类所有方法,然后在虚拟子类中搞一点事情