java 代理方式
代理是一种常用的设计模式,在Java中有三种常见的代理方式:
静态代理:
静态代理是通过手动编写代理类来实现的,代理类和被代理类实现相同的接口,并在代理类中调用被代理类的方法,并可以在方法前后添加一些额外的逻辑。静态代理的缺点是需要为每个被代理类编写一个代理类,代码量较大。
示例代码:
// 定义接口
interface Subject {
void doSomething();
}
// 实现被代理类
class RealSubject implements Subject {
public void doSomething() {
System.out.println("RealSubject do something");
}
}
// 实现代理类
class Proxy implements Subject {
private Subject realSubject;
public Proxy(Subject realSubject) {
this.realSubject = realSubject;
}
public void doSomething() {
System.out.println("Before doSomething");
realSubject.doSomething();
System.out.println("After doSomething");
}
}
// 使用代理类
public static void main(String[] args) {
RealSubject realSubject = new RealSubject();
Proxy proxy = new Proxy(realSubject);
proxy.doSomething();
}
动态代理:
动态代理是在运行时生成代理对象,无需手动编写代理类。Java中的动态代理是通过java.lang.reflect.Proxy和java.lang.reflect.InvocationHandler接口实现的。动态代理只需要编写一个InvocationHandler接口的实现类,通过反射机制动态生成代理对象,可以代理任意实现了接口的类。
示例代码:
// 定义接口
interface Subject {
void doSomething();
}
// 实现被代理类
class RealSubject implements Subject {
public void doSomething() {
System.out.println("RealSubject do something");
}
}
// 实现InvocationHandler接口
class DynamicProxy implements InvocationHandler {
private Object target;
public DynamicProxy(Object target) {
this.target = target;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("Before doSomething");
Object result = method.invoke(target, args);
System.out.println("After doSomething");
return result;
}
}
// 使用动态代理
public static void main(String[] args) {
RealSubject realSubject = new RealSubject();
InvocationHandler handler = new DynamicProxy(realSubject);
Subject proxy = (Subject) Proxy.newProxyInstance(
realSubject.getClass().getClassLoader(),
realSubject.getClass().getInterfaces(),
handler);
proxy.doSomething();
}
CGLIB代理:
CGLIB(Code Generation Library)代理是通过生成被代理类的子类来实现的,无需实现接口。CGLIB代理通过继承的方式实现代理,覆盖被代理类的方法,并可以在方法前后添加额外的逻辑。CGLIB代理在运行时生成字节码,因此比动态代理稍微慢一些。
示例代码:
// 实现被代理类
class RealSubject {
public void doSomething() {
System.out.println("RealSubject do something");
}
}
// 实现MethodInterceptor接口
class CglibProxy implements MethodInterceptor {
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
System.out.println("Before doSomething");
Object result = proxy.invokeSuper(obj, args);
System.out.println("After doSomething");
return result;
}
}
// 使用CGLIB代理
public static void main(String[] args) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(RealSubject.class);
enhancer.setCallback(new CglibProxy());
RealSubject proxy = (RealSubject) enhancer.create();
proxy.doSomething();
}