设计模式之【动态代理】

发布于:2025-07-08 ⋅ 阅读:(12) ⋅ 点赞:(0)

目录

动态代理中存在的概念

JDK动态代理

代理工厂【ProxyFactory】实现【InvocationHandler】

目标类的接口【TargetInterface】

目标类【Target】实现了接口

测试类【JDKDynamicProxyTest】

CGLIB动态代理

添加Maven依赖

代理工厂【ProxyFactory】实现【MethodInterceptor】

目标类【Target】没有实现接口 

 测试类【CGLIBDynamicProxyTest】


动态代理中存在的概念

  • 目标类、目标对象【target】
  • 代理类、代理对象【proxy】
  • 增强逻辑【advice】

JDK动态代理

  • 要求:目标类必须要实现接口
  • 原理:和目标类实现同一个接口,对目标类进行增强

代理工厂【ProxyFactory】实现【InvocationHandler】

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class ProxyFactory<T> implements InvocationHandler {
    // 目标对象
    private final T target;

    public ProxyFactory(T target) {
        this.target = target;
    }

    /**
     * 获取代理对象
     */
    @SuppressWarnings("all")
    public T getProxy() {
        // 类加载器
        ClassLoader classLoader = getClassLoader();
        // 接口
        Class<?>[] interfaces = getInterfaces(target);
        // 返回代理对象
        return (T) Proxy.newProxyInstance(classLoader, interfaces, this);
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Object obj;
        try {
            // 前置增强
            before();
            obj = method.invoke(target, args);
            // 返回后增强
            afterReturning();
            return obj;
        } catch (Throwable throwable) {
            // 异常后增强
            afterThrowing();
            throw throwable;
        } finally {
            // 后置增强
            after();
        }
    }

    private ClassLoader getClassLoader() {
        return Thread.currentThread().getContextClassLoader();
    }

    private Class<?>[] getInterfaces(T target) {
        return target.getClass().getInterfaces();
    }

    private void before() {
        System.out.println("before...");
    }

    private void after() {
        System.out.println("after...");
    }

    private void afterThrowing() {
        System.out.println("afterThrowing...");
    }

    private void afterReturning() {
        System.out.println("afterReturning...");
    }
}

目标类的接口【TargetInterface】

public interface TargetInterface {
    void method();
}

目标类【Target】实现了接口

public class Target implements TargetInterface {
    public void method() {
        System.out.println("执行目标方法...");
    }
}

测试类【JDKDynamicProxyTest】

/**
 * 测试JDK动态代理
 */
public class JDKDynamicProxyTest {
    public static void main(String[] args) {
        // 目标对象
        TargetInterface target = new Target();
        ProxyFactory<TargetInterface> proxyFactory = new ProxyFactory<>(target);
        // 代理对象
        TargetInterface proxy = proxyFactory.getProxy();
        // 目标对象方法执行逻辑 + 增强逻辑
        proxy.method();
    }
}

CGLIB动态代理

  • 要求:目标类非final关键字修饰
  • 原理:将目标类作为父类,通过子类来对父类进行增强

添加Maven依赖

<!--CGLIB依赖-->
<dependency>
    <groupId>cglib</groupId>
    <artifactId>cglib</artifactId>
    <version>3.3.0</version>
</dependency>

代理工厂【ProxyFactory】实现【MethodInterceptor】

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

public class ProxyFactory<T> implements MethodInterceptor {

    /**
     * 获取代理对象
     */
    @SuppressWarnings("all")
    public T getProxy(Class<T> cls) {
        Enhancer enhancer = new Enhancer();
        // 设置父类
        enhancer.setSuperclass(cls);
        // 设置回调
        enhancer.setCallback(this);
        // 返回创建的代理对象
        return (T) enhancer.create();
    }


    @Override
    public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
        Object result;
        try {
            System.out.println("前置增强...");
            // 调用目标对象的方法
            result = methodProxy.invokeSuper(o, args);
            System.out.println("正常返回时增强...");
            return result;
        } catch (Throwable throwable) {
            System.out.println("异常时增强...");
            throw throwable;
        } finally {
            System.out.println("后置增强...");
        }
    }
}

目标类【Target】没有实现接口 

public class Target {
    public void method() {
        System.out.println("目标方法执行++++++++");
    }
}

 测试类【CGLIBDynamicProxyTest】

public class CGLIBDynamicProxyTest {
    public static void main(String[] args) {
        ProxyFactory<Target> proxyFactory = new ProxyFactory<>();
        // 代理对象
        Target proxy = proxyFactory.getProxy(Target.class);
        // 原始逻辑 + 增强逻辑
        proxy.method();
    }
}


网站公告

今日签到

点亮在社区的每一天
去签到