静态代理和动态代理是Java中常用的两种代理模式,用于为目标对象提供额外的功能。以下是它们的主要区别:
静态代理
-
代理类在编译时确定:
- 静态代理类在编译时就已经存在,并且需要手动编写。
-
代理类和目标类实现相同的接口:
- 代理类和被代理的目标类都需要实现相同的接口。
-
实现较为简单:
- 由于是手动编写代理类,结构清晰,适合简单的场景。
-
不易维护:
- 如果接口方法较多,代理类需要实现所有方法,这会增加代码量和维护成本。
-
性能较好:
- 因为代理类是编译时生成的,所以在运行时的性能开销较低。
动态代理
-
代理类在运行时生成:
- 动态代理类是在程序运行时通过反射机制动态生成的。
-
可以代理任意接口:
- 只需要一个InvocationHandler接口就可以代理任意接口的实现类。
-
实现较为复杂:
- 动态代理依赖于Java反射机制,代码相对复杂一些,但更灵活。
-
易于维护:
- 因为不需要为每个接口手动编写代理类,所以代码量较少,维护成本较低。
-
性能开销:
- 因为动态代理使用了反射机制,在运行时会有一定的性能开销。
示例代码
静态代理示例
public interface Subject {
void request();
}
public class RealSubject implements Subject {
public void request() {
System.out.println("RealSubject request");
}
}
public class StaticProxy implements Subject {
private RealSubject realSubject;
public StaticProxy(RealSubject realSubject) {
this.realSubject = realSubject;
}
public void request() {
System.out.println("StaticProxy before request");
realSubject.request();
System.out.println("StaticProxy after request");
}
}
public class Client {
public static void main(String[] args) {
RealSubject realSubject = new RealSubject();
StaticProxy proxy = new StaticProxy(realSubject);
proxy.request();
}
}
动态代理示例
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 {
public void request() {
System.out.println("RealSubject request");
}
}
public class DynamicProxyHandler implements InvocationHandler {
private Object realSubject;
public DynamicProxyHandler(Object realSubject) {
this.realSubject = realSubject;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("DynamicProxy before request");
Object result = method.invoke(realSubject, args);
System.out.println("DynamicProxy after request");
return result;
}
}
public class Client {
public static void main(String[] args) {
RealSubject realSubject = new RealSubject();
InvocationHandler handler = new DynamicProxyHandler(realSubject);
Subject proxy = (Subject) Proxy.newProxyInstance(realSubject.getClass().getClassLoader(), new Class[]{Subject.class}, handler);
proxy.request();
}
}
静态代理和动态代理各有优缺点,选择哪种方式取决于具体的使用场景和需求。
标签:静态,RealSubject,request,代理,realSubject,动态,public,Subject From: https://blog.csdn.net/Gemini1995/article/details/140917601