代理模式
代理模式
- 功能增强:在原有的功能上,增加了额外的功能,
- 控制访问:代理类不让你访问目标对象,只能通过代理对象来控制目标对象。
使用代理对象包装目标对象,每次访问目标对象时,都通过代理对象来访问。
代理对象就可以控制目标对象实现功能的过程,并且在其中添加额外的功能.
两个一致:
-
代理对象和目标对象 功能一致 :代理对象和目标对象实现相同的接口
-
结果一致 : 代理对象实现功能的过程,就是目标对象实现功能的过程。
静态代理
代理类是自己手动实现的,
目标类是确定好的。
- 核心功能前
- 核心功能后
- catch中
- finally中
动态代理
1. JDK动态代理 (Interface Proxy)
JDK动态代理主要依赖于java.lang.reflect.Proxy类和java.lang.reflect.InvocationHandler接口。JDK动态代理适用于那些实现了接口的类。
-
实现原理:
- 利用反射机制在运行时动态地创建一个实现了给定接口列表的新类。
- 这个新类将代理原始的对象,并且所有的方法调用都将被转发到一个实现了
InvocationHandler接口的实例上。 InvocationHandler的invoke方法会在每次代理对象的方法被调用时触发。
-
示例代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25public interface MyInterface {
void doSomething();
}
InvocationHandler handler = new InvocationHandler() {
private final MyInterface target;
public MyInterfaceHandler(MyInterface target) {
this.target = target;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("Before method call");
Object result = method.invoke(target, args);
System.out.println("After method call");
return result;
}
};
MyInterface myInterface = (MyInterface) Proxy.newProxyInstance(
MyInterface.class.getClassLoader(),
new Class<?>[]{MyInterface.class},
handler
); -
优点:
- 无需编写代理类的源代码。
- 代理类在运行时生成,减少了编码工作量。
-
缺点:
- 只能代理实现了接口的类。
- 如果没有实现接口,则无法使用JDK动态代理。
2. CGLIB动态代理 (Subclass Proxy)
CGLIB(Code Generation Library)是一个强大的高性能的代码生成库,它使用ASM(字节码操作库)来动态生成代理类。
-
实现原理:
- 通过字节码技术为一个类创建一个子类实例。
- 这个子类重写了父类的所有非
final方法,并且在方法前后添加额外的逻辑。 - 使用
Enhancer类来创建动态代理类。
-
示例代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
public class MyClass {
public void doSomething() {
System.out.println("Doing something...");
}
}
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(MyClass.class);
enhancer.setCallback(new MethodInterceptor() {
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
System.out.println("Before method call");
Object result = proxy.invokeSuper(obj, args);
System.out.println("After method call");
return result;
}
});
MyClass myClass = (MyClass) enhancer.create(); -
优点:
- 不需要目标类实现接口。
- 可以代理任意类,只要该类不是
final的,且其方法不是final的。
-
缺点:
- 生成的代理类比JDK动态代理要稍微慢一点。
- 不能代理
final类和final方法。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Orange's_Blog!
评论
