静态代理和动态代理的区别
时间: 2024-06-02 08:07:46 浏览: 40
静态代理和动态代理都是用于代理对象的操作,但它们的实现方式不同。动态代理是在运行时利用反射机制动态生成代理对象,代理类是在程序运行时动态生成的。而静态代理是在编译时就已经生成代理类,代理类是编写代码时就生成的。
动态代理相对于静态代理的优点在于可以节省编写代理类的时间和代码量,同时也更加灵活和易于扩展。不过动态代理的缺点在于它的执行效率相对于静态代理略低,且只能代理实现了接口的类。
总之,在不同的情况下,我们可以根据实际情况选择使用静态代理或者动态代理。
相关问题
静态代理和动态代理区别
静态代理和动态代理是两种常见的代理模式,它们的主要区别在于代理类的生成方式和使用时机。
静态代理是在编译时期就已经确定代理类的代码,代理类和被代理类的关系在编译时就确定了。在静态代理中,代理类需要手动编写或生成,代理类和被代理类实现相同的接口或继承相同的父类,并在代理类中调用被代理类的方法。静态代理的优点是简单易懂,缺点是每个被代理类都需要对应一个代理类,当被代理类较多时,代码量会增加。
动态代理是在运行时动态生成代理类的代码,代理类和被代理类的关系在运行时确定。在动态代理中,代理类不需要手动编写或生成,而是通过Java的反射机制在运行时动态生成。动态代理的优点是可以减少代码量,只需要一个通用的代理类即可处理多个被代理类,缺点是相比静态代理稍微复杂一些。
总结一下:
- 静态代理在编译时期确定代理类的代码,需要手动编写或生成代理类。
- 动态代理在运行时动态生成代理类的代码,不需要手动编写或生成代理类。
- 静态代理适用于代理类数量较少的情况,动态代理适用于代理类数量较多的情况。
java静态代理和动态代理的区别
### Java 中静态代理与动态代理的区别
#### 静态代理的特点
在静态代理中,客户端通过代理类间接调用实际业务逻辑的对象方法。这种方式下,代理类和真实主题都实现了相同的接口,并且代理类持有对真实主题的引用[^4]。
对于静态代理而言,一旦定义好了一个具体的代理类之后,在编译期就已经确定下来了;这意味着如果想要更改或增加新的行为时就需要重新创建一个新的代理类来满足需求[^1]。
```java
// 定义一个接口
public interface Service {
void doSomething();
}
// 实现该接口的真实服务提供者
class RealService implements Service {
@Override
public void doSomething() {
System.out.println("Real service is doing something.");
}
}
// 创建一个具体的服务代理类也实现同样的接口并持有一个指向真正执行者的引用
class StaticProxy implements Service {
private final Service realService;
public StaticProxy(Service realService) {
this.realService = realService;
}
@Override
public void doSomething() {
// 增强前处理...
System.out.println("Before calling the actual method");
// 调用真正的业务逻辑
realService.doSomething();
// 增强后处理...
System.out.println("After calling the actual method");
}
}
```
#### 动态代理的优势
相比之下,JDK 提供了一种更加灵活的方式——即所谓的“动态代理”。它允许程序在运行期间根据传入参数自动生成相应的代理实例而无需提前编写任何额外代码[^3]。
为了支持这种机制,Java SE API 提供了 `java.lang.reflect.InvocationHandler` 接口以及 `java.lang.reflect.Proxy` 类用于生成代理对象。当某个方法被调用时会触发 InvocationHandler 的 invoke 方法来进行拦截操作[^2]。
```java
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
// 自定义 invocation handler 来指定如何响应来自代理对象的方法请求
class DynamicInvocationHandler implements InvocationHandler {
private Object target;
public DynamicInvocationHandler(Object target){
this.target=target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)throws Throwable{
// 执行前置增强逻辑 ...
System.out.println("Before invoking " + method.getName());
// 将调用转发给原始的目标对象
var result=method.invoke(target,args);
// 进行后续增强逻辑 ...
System.out.println("After invoking " + method.getName());
return result;
}
}
// 使用反射创建代理对象
Service dynamicProxyInstance=(Service) Proxy.newProxyInstance(
RealService.class.getClassLoader(),
new Class[]{Service.class},
new DynamicInvocationHandler(new RealService())
);
dynamicProxyInstance.doSomething();
```
阅读全文