如何代理java
代理模式的基本概念
代理模式是一种设计模式,通过创建一个代理对象来控制对真实对象的访问。代理对象可以在调用真实对象的方法前后添加额外逻辑,例如权限检查、日志记录或延迟加载。
静态代理实现
静态代理需要手动创建代理类,代理类和目标类实现相同的接口。
// 定义接口
public interface Subject {
void request();
}
// 真实对象
public class RealSubject implements Subject {
@Override
public void request() {
System.out.println("RealSubject handles the request.");
}
}
// 代理类
public class ProxySubject implements Subject {
private RealSubject realSubject;
@Override
public void request() {
if (realSubject == null) {
realSubject = new RealSubject();
}
System.out.println("Proxy handles pre-processing.");
realSubject.request();
System.out.println("Proxy handles post-processing.");
}
}
// 使用代理
public class Client {
public static void main(String[] args) {
Subject proxy = new ProxySubject();
proxy.request();
}
}
动态代理实现
动态代理通过反射机制在运行时生成代理对象,无需手动编写代理类。Java提供了java.lang.reflect.Proxy和InvocationHandler实现动态代理。
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
// 定义接口
public interface Subject {
void request();
}
// 真实对象
public class RealSubject implements Subject {
@Override
public void request() {
System.out.println("RealSubject handles the request.");
}
}
// 实现InvocationHandler
public class DynamicProxyHandler implements InvocationHandler {
private Object target;
public DynamicProxyHandler(Object target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("DynamicProxy pre-processing.");
Object result = method.invoke(target, args);
System.out.println("DynamicProxy post-processing.");
return result;
}
}
// 使用动态代理
public class Client {
public static void main(String[] args) {
RealSubject realSubject = new RealSubject();
Subject proxy = (Subject) Proxy.newProxyInstance(
realSubject.getClass().getClassLoader(),
realSubject.getClass().getInterfaces(),
new DynamicProxyHandler(realSubject)
);
proxy.request();
}
}
CGLIB动态代理
对于没有实现接口的类,可以使用CGLIB库实现动态代理。CGLIB通过继承目标类生成子类来实现代理。

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
// 目标类(无需实现接口)
public class RealSubject {
public void request() {
System.out.println("RealSubject handles the request.");
}
}
// 实现MethodInterceptor
public class CglibProxyInterceptor implements MethodInterceptor {
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
System.out.println("CGLIB pre-processing.");
Object result = proxy.invokeSuper(obj, args);
System.out.println("CGLIB post-processing.");
return result;
}
}
// 使用CGLIB代理
public class Client {
public static void main(String[] args) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(RealSubject.class);
enhancer.setCallback(new CglibProxyInterceptor());
RealSubject proxy = (RealSubject) enhancer.create();
proxy.request();
}
}
代理模式的应用场景
- 远程代理:控制对远程对象的访问(如RPC调用)。
- 虚拟代理:延迟加载资源密集型对象(如图片或文件)。
- 保护代理:控制对敏感对象的访问权限。
- 日志代理:在方法调用前后记录日志。
注意事项
- 动态代理只能代理接口方法,CGLIB可以代理类方法。
- 动态代理性能略低于静态代理,但灵活性更高。
- CGLIB通过继承实现代理,因此无法代理
final类或方法。






