引言
无论在系统设计或者代码开发中都有着代理设计思维的身影。比如在路由反向代理服务器、Spring框架中的AOP思维。今天来记录一下另一个简单的设计模式-代理设计模式(Proxy Pattern)
动态代理模式
代理属于结构型模式的一种。它提供了一种替身或占位符来控制对被代理对象的访问。通过代理可以添加额外的功能,比如访问控制、日志记录、延迟加载、权限校验等,而不会改变原始对象的接口和功能。
按照种类,代理可以分为静态代理和动态代理,接下来介绍下动态代理。
动态代理:它允许我们在不修改原有类代码的基础上,通过在运行时创建一个代理对象来包裹原始对象,从而扩展或控制对原始对象的访问。
Java中提供了两种实现动态代理的方式:JDK动态代理和CGLIB动态代理。先介绍下JDK动态代理。
例举一个demo,该demo展示了Java动态代理的基本用法,代码如下:
/**
* @堆代码 duidaima.com
* @date 2024/7/1 19:00
*/
public class Main {
public static void main(String[] args) {
Hello hello = new Hello();
JDKDynamicProxy JDKDynamicProxy = new JDKDynamicProxy(hello);
IHello proxyInstance = (IHello) JDKDynamicProxy.getProxyInstance();
proxyInstance.sayHello();
}
}
// 代理类
class JDKDynamicProxy {
Object target = new Object();
public JDKDynamicProxy(Object target) {
this.target = target;
}
public Object getProxyInstance(){
return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(),
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("代理开始。。。");
Object res = method.invoke(target, args);
System.out.println("代理结束。。。");
return res;
}
});
}
}
// 目标接口
interface IHello{
void sayHello();
}
// 目标类
class Hello implements IHello{
@Override
public void sayHello() {
System.out.println("hello world!!!");
}
}
代码解析:
• 接口 IHello:定义了一个方法 sayHello(),这是被代理对象需要实现的接口。
• 实现类 Hello:实现了接口 IHello,具体实现了 sayHello() 方法,用于输出 "hello world!!!"。
• 动态代理类 JDKDynamicProxy:构造函数接受一个目标对象(需要被代理的对象),并通过传入的目标对象,获取其类加载器和实现的接口信息。getProxyInstance() 方法利用 Proxy.newProxyInstance() 创建代理实例。这个方法需要三个参数:目标对象的类加载器、目标对象实现的接口类型数组,以及一个 InvocationHandler 实现对象。在每次代理方法调用时,都会执行这个InvocationHandler的 invoke() 方法。
小结
相较于静态代理,动态代理更适合于需要高度灵活性、维护性和扩展性的场景,尤其适合于AOP应用和动态管理代理行为的需求。