静态代理与动态代理的区别
字数
1045 字
阅读时间
5 分钟
[!summary]
- 静态代理通过手动创建的代理类,在方法调用的前后添加额外的操作,但每个类都需要单独编写代理类,增加了重复劳动。
- 动态代理则通过反射机制在运行时创建代理类,灵活性高,不需要为每个类编写代理,但使用反射可能会影响性能,调试也稍微复杂。
两种代理方式各有优缺点,具体使用时可以根据实际需求选择合适的方式。
静态代理和动态代理的主要区别在于代理类的生成方式、灵活性以及实现的复杂程度:
静态代理:
- 定义:代理类在编译期就已经存在,必须由开发者手动编写或通过工具生成。代理类直接依赖于真实类。
- 优点:实现简单,容易理解。
- 缺点:需要为每个被代理的类单独编写代理类,增加代码量,灵活性较低。
动态代理:
- 定义:代理类在程序运行时动态生成,不需要开发者显式定义代理类。通过反射机制实现代理,能够在运行时灵活调用方法。
- 优点:减少重复代码,灵活性高。可以应用于多个接口,不需要单独为每个服务编写代理类。
- 缺点:基于反射机制,性能可能稍微低于静态代理,调试难度较大。
1 静态代理示例
1.1 接口定义
java
// 服务接口
public interface Service {
void serve();
}
1.2 真实服务类
java
// 真实服务类
public class RealService implements Service {
@Override
public void serve() {
System.out.println("真实服务处理请求");
}
}
1.3 静态代理类
java
// 代理类
public class ServiceProxy implements Service {
private Service realService;
// 构造函数,传入真实服务对象
public ServiceProxy(Service realService) {
this.realService = realService;
}
@Override
public void serve() {
// 调用真实方法前的操作
System.out.println("代理:方法调用前执行操作");
// 调用真实服务对象的方法
realService.serve();
// 调用真实方法后的操作
System.out.println("代理:方法调用后执行操作");
}
}
1.4 静态代理使用
java
public class StaticProxyDemo {
public static void main(String[] args) {
// 创建真实服务对象
Service realService = new RealService();
// 创建代理对象,并将真实对象传递给代理对象
Service proxy = new ServiceProxy(realService);
// 通过代理对象调用方法
proxy.serve();
}
}
1.5 输出结果
代理:方法调用前执行操作
真实服务处理请求
代理:方法调用后执行操作
2 动态代理示例
2.1 接口定义
java
// 服务接口
public interface Service {
void serve();
}
2.2 真实服务类
java
// 真实服务类
public class RealService implements Service {
@Override
public void serve() {
System.out.println("真实服务处理请求");
}
}
2.3 动态代理处理类
java
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
// 动态代理处理类
public class ServiceInvocationHandler implements InvocationHandler {
private Object target;
// 构造函数,传入真实对象
public ServiceInvocationHandler(Object target) {
this.target = target;
}
// 处理方法调用
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 在调用真实方法前添加一些操作
System.out.println("代理:方法调用前执行操作");
// 调用真实对象的方法
Object result = method.invoke(target, args);
// 在调用真实方法后添加一些操作
System.out.println("代理:方法调用后执行操作");
return result;
}
}
2.4 动态代理使用
java
import java.lang.reflect.Proxy;
public class DynamicProxyDemo {
public static void main(String[] args) {
// 创建真实对象
Service realService = new RealService();
// 创建动态代理
Service proxyService = (Service) Proxy.newProxyInstance(
realService.getClass().getClassLoader(),
realService.getClass().getInterfaces(),
new ServiceInvocationHandler(realService)
);
// 调用代理对象的方法
proxyService.serve();
}
}
2.5 输出结果
代理:方法调用前执行操作
真实服务处理请求
代理:方法调用后执行操作