Java动态代理使用

前置环境

有如下接口Worker

public interface Worker {  
    String work(String string);  
}

实现一个PrintWorker,工作是把输入的参数输出到控制台并返回

public class PrintWorker implements Worker {  
    @Override  
    public String work(String string) {  
        System.out.println(string);  
        return string;  
    }  
}

通过动态代理,实现在work方法被调用之前,增加时间戳的打印

JDK 动态代理

调用代理对象的任何方法,实际上都是调用InvocationHandlerinvoke方法,在invoke方法内定义代理对象需要额外处理的逻辑

invoke方法的proxy参数一般用于链式编程,返回代理对象自身

import java.lang.reflect.InvocationHandler;  
import java.lang.reflect.Method;  
  
public class TimerInvocationHandler implements InvocationHandler {  

    // 被代理对象
    private Worker worker;  
  
    public TimerInvocationHandler(Worker worker) {  
        this.worker = worker;  
    }  
  
    @Override  
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {  
        if ("work".equals(method.getName())) {  
            System.out.println(System.currentTimeMillis());  
        }  
        return method.invoke(worker, args);  
    }  
}

获取代理对象,并调用work方法

import java.lang.reflect.Proxy;

@Test  
void testJdkProxy() {  
    Worker printWorker = new PrintWorker();  
    TimerInvocationHandler timerInvocationHandler = new TimerInvocationHandler(printWorker);  
    ClassLoader classLoader = PrintWorker.class.getClassLoader();  
    Class<?>[] interfaces = PrintWorker.class.getInterfaces();  
    Worker proxyWorker = (Worker) Proxy.newProxyInstance(classLoader, interfaces, timerInvocationHandler);  
    proxyWorker.work("Hello");
    System.out.println("result:" + result);
}

控制台输出

1680566771120
Hello
result:Hello

cglib

Maven依赖

<dependency>  
    <groupId>cglib</groupId>  
    <artifactId>cglib</artifactId>  
    <version>3.3.0</version>  
</dependency>

调用代理对象的任何方法,实际上都是调用MethodInterceptorintercept方法,在intercept方法内定义代理对象需要额外处理的逻辑

intercept方法的o参数一般用于链式编程,返回代理对象自身

import net.sf.cglib.proxy.MethodInterceptor;  
import net.sf.cglib.proxy.MethodProxy;  
  
import java.lang.reflect.Method;  
  
public class TimerInterceptor implements MethodInterceptor {  
    @Override  
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {  
        if ("work".equals(method.getName())) {  
            System.out.println(System.currentTimeMillis());  
        }  
        return methodProxy.invokeSuper(o, objects);  
    }  
}

获取代理对象,并调用work方法

import net.sf.cglib.proxy.Enhancer;

@Test  
void testCglibProxy() {  
    Enhancer enhancer = new Enhancer();  
    enhancer.setClassLoader(PrintWorker.class.getClassLoader());  
    enhancer.setSuperclass(PrintWorker.class);  
    enhancer.setCallback(new TimerInterceptor());  
    Worker proxyWorker = (Worker) enhancer.create();  
    String result = proxyWorker.work("Hello");  
    System.out.println("result:" + result);  
}

控制台输出

1680567996153
Hello
result:Hello