(目录)
需要代理的对象
// 接口
public interface PayService {
void pay();
}
// 实现
public class AliPayService implements PayService {
@Override
public void pay() {
System.out.println("AliPayService");
}
}
1. JDK 动态代理
在 JDK 动态代理中,被代理类必须实现一个或多个接口,并通过 InvocationHandler 接口来实现代理类的具体逻辑。
实现 InvocationHandler
package com.example.demo.proxy.handler;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class LogInvocationHandler implements InvocationHandler {
private Object target;
public LogInvocationHandler(Object target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("log before invoke");
Object result = method.invoke(this.target, args);
System.out.println("log after invoke");
return result;
}
}
测试类
package com.example.demo.proxy;
import com.example.demo.proxy.handler.LogInvocationHandler;
import com.example.demo.proxy.impl.AliPayService;
import org.junit.Test;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
public class InvocationHandlerTests {
@Test
public void testLogInvocationHandler() {
PayService payService = new AliPayService();
// 创建一个代理类:通过被代理类、被代理实现的接口、方法调用处理器来创建
PayService payServiceProxy = (PayService) Proxy.newProxyInstance(
payService.getClass().getClassLoader(),
new Class[]{PayService.class},
new LogInvocationHandler(payService)
);
payServiceProxy.pay();
// log before invoke
// AliPayService
// log after invoke
}
}
2. CGLIB 动态代理
CGLIB 动态代理是一种使用 CGLIB 库来实现动态代理的技术。在 CGLIB 动态代理中,代理类不需要实现接口,而是通过继承被代理类来实现代理。
package com.example.demo.proxy.handler;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
public class LogMethodInterceptor implements MethodInterceptor {
// 被代理对象
private Object target;
public LogMethodInterceptor(Object target) {
this.target = target;
}
@Override
public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
System.out.println("log before invoke");
Object result = method.invoke(this.target, args);
System.out.println("log after invoke");
return result;
}
}
测试类
package com.example.demo.proxy;
import com.example.demo.proxy.handler.LogMethodInterceptor;
import com.example.demo.proxy.impl.AliPayService;
import org.junit.Test;
import org.springframework.cglib.proxy.Enhancer;
public class LogMethodInterceptorTests {
@Test
public void testLogMethodInterceptor() {
PayService target = new AliPayService();
PayService proxy = (PayService) Enhancer.create(
target.getClass(),
new LogMethodInterceptor(target)
);
proxy.pay();
// log before invoke
// AliPayService
// log after invoke
}
}
总结
实现方法 | 实现技术 |
---|---|
JDK 动态代理 | 实现接口 |
CGLIB 动态代理 | 继承父类 |