代理是一种常见的设计模式,它允许一个对象(代理对象)控制另一个对象(真实对象)的访问。在Java中,代理主要分为静态代理和动态代理两种方式,而CGLIB代理是动态代理的一种变体。
1. 静态代理
静态代理是在编译时期就已经确定好代理类,并固定代理关系。下面是一个简单的示例:
// 接口
interface Subject {
void request();
}
// 真实对象
class RealSubject implements Subject {
@Override
public void request() {
System.out.println("RealSubject: Handling request.");
}
}
// 代理对象
class ProxySubject implements Subject {
private RealSubject realSubject;
public ProxySubject(RealSubject realSubject) {
this.realSubject = realSubject;
}
@Override
public void request() {
System.out.println("ProxySubject: Before handling request.");
realSubject.request();
System.out.println("ProxySubject: After handling request.");
}
}
// 客户端
public class StaticProxyExample {
public static void main(String[] args) {
RealSubject realSubject = new RealSubject();
ProxySubject proxySubject = new ProxySubject(realSubject);
proxySubject.request();
}
}
2. 动态代理
动态代理是在运行时期生成代理类,无需在编译时期确定代理关系。Java中的动态代理通常使用java.lang.reflect.Proxy
类和java.lang.reflect.InvocationHandler
接口来实现。下面是一个简单的动态代理示例:
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
// 接口
interface Subject {
void request();
}
// 真实对象
class RealSubject implements Subject {
@Override
public void request() {
System.out.println("RealSubject: Handling request.");
}
}
// 动态代理处理器
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: Before handling request.");
Object result = method.invoke(target, args);
System.out.println("DynamicProxy: After handling request.");
return result;
}
}
// 客户端
public class DynamicProxyExample {
public static void main(String[] args) {
RealSubject realSubject = new RealSubject();
InvocationHandler handler = new DynamicProxyHandler(realSubject);
Subject proxySubject = (Subject) Proxy.newProxyInstance(
Subject.class.getClassLoader(),
new Class[]{Subject.class},
handler);
proxySubject.request();
}
}
3. CGLIB代理
CGLIB代理是一种基于字节码的代理方式,它不需要接口支持。下面是一个简单的CGLIB代理示例:
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
// 真实对象
class RealSubject {
public void request() {
System.out.println("RealSubject: Handling request.");
}
}
// CGLIB代理处理器
class CglibProxy implements MethodInterceptor {
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
System.out.println("CglibProxy: Before handling request.");
Object result = proxy.invokeSuper(obj, args);
System.out.println("CglibProxy: After handling request.");
return result;
}
}
// 客户端
public class CglibProxyExample {
public static void main(String[] args) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(RealSubject.class);
enhancer.setCallback(new CglibProxy());
RealSubject cglibProxy = (RealSubject) enhancer.create();
cglibProxy.request();
}
}