欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 文旅 > 八卦 > 五、代理模式

五、代理模式

2025/2/22 16:59:04 来源:https://blog.csdn.net/duanlei123456/article/details/141828938  浏览:    关键词:五、代理模式

代理模式(Proxy Pattern)是一种结构型设计模式,它为其他对象提供一个代理以控制对这个对象的访问。代理对象通常会对真实对象的请求进行一些处理(例如延迟初始化、访问控制、日志记录等),它能够在不改变目标对象的情况下,给目标对象添加额外的功能。

主要组成部分:

  1. 主题接口(Subject)

    • 定义了真实对象和代理对象的共同接口。客户端通过这个接口与真实对象交互。
  2. 真实主题(Real Subject)

    • 实现了主题接口,代表真实的对象,包含实际的业务逻辑。
  3. 代理(Proxy)

    • 也是实现主题接口的类,它持有一个真实主题的引用,并对真实主题的请求进行处理。

优点:

  1. 控制访问:可以在代理类中添加访问控制逻辑,从而增强安全性。

  2. 延迟加载:代理对象可以在实际需要时才创建真实对象,提高性能。

  3. 更好的管理:可以通过代理对请求进行日志记录、缓存等管理。

  4. 透明性:客户端与真实对象之间的交互是透明的,因为它们通过相同的接口来访问。

使用场景:

  • 当需要控制对某个对象的访问时(例如,权限控制)。
  • 当需要在访问对象时进行附加操作时(如延迟加载)。
  • 当需要对访问对象进行代理(如网络请求或缓存)。

静态代理

GO: 

golang 实现静态代理,有 Golang 和 java 的差异性,我们无法比较方便的利用反射实现动态代理,但是我们可以利用** go generate **实现类似的效果,并且这样实现有两个比较大的好处,一个是有静态代码检查,我们在编译期间就可以及早发现问题,第二个是性能会更好

package proxyimport ("fmt""log""time"
)// IUser 接口
type IUser interface {// Login 登陆函数Login(username string, password string) error
}// User 用户实现IUser接口
type User struct {
}// Login 用户登录
func (u *User) Login(username string, password string) error {// 不实现细节fmt.Println("登陆成功......")return nil
}// UserProxy 代理类 也实现 IUser 接口
type UserProxy struct {user *User
}// NewUserProxy NewUserProxy
func NewUserProxy(user *User) *UserProxy {return &UserProxy{user: user,}
}func (u *UserProxy) Login(username string, password string) error {// before 这里可能会有一些统计的逻辑start := time.Now()// 这里是原有的业务逻辑if err := u.user.Login(username, password); err != nil {return err}// after 这里可能也有一些监控统计的逻辑log.Printf("user login cost time: %s", time.Now().Sub(start))return nil
}
package proxyimport ("github.com/stretchr/testify/require""testing"
)func TestProxy(t *testing.T) {// 构建代理对象proxy := NewUserProxy(&User{})//调用登陆err := proxy.Login("test", "password")require.Nil(t, err)
}
JAVA:
public interface IUser {public void login(String username, String password);
}
public class User implements IUser{@Overridepublic void login(String username, String password) {// 不做具体实现System.out.println("登陆成功");}
}
public class UserProxy implements IUser{private User user;@Overridepublic void login(String username, String password) {// 可以在请求之前进行某些处理if (user == null) {user = new User();}System.out.println("Proxy: Pre-processing before request.");user.login(username, password); // 转发请求System.out.println("Proxy: Post-processing after request.");}
}

 

public class ProxyTest {@Test(description = "静态代理")public void proxyTest(){UserProxy userProxy = new UserProxy();userProxy.login("xxx", "yyy");}
}

动态代理 

GO:待补充。。。。
JAVA:
1. 基于 JDK 的动态代理

JDK 的动态代理通过 java.lang.reflect.Proxy 类和 InvocationHandler 接口来实现。它需要指定一个接口,然后通过代理对象来调用真实对象的方法。

使用步骤:
  1. 定义接口
  2. 创建真实主题类
  3. 实现 InvocationHandler 接口
  4. 创建代理对象
  5. 调用方法
//1.定义接口
public interface Subject {public void request();
}
//2.创建真实主题类
public class RealSubject implements Subject{@Overridepublic void request() {System.out.println("RealSubject: Handling request.");}
}
//3.动态代理处理器 实现 InvocationHandler 接口
public class DynamicProxyHandler implements InvocationHandler {private Object target;public DynamicProxyHandler(Object target) {this.target = target;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {// 在调用目标方法之前执行一些操作System.out.println("Proxy: Pre-processing before request.");Object result = method.invoke(target, args); // 调用真实方法// 在调用目标方法之后执行一些操作System.out.println("Proxy: Post-processing after request.");return result;}
}
@Test(description = "动态代理-JDK")public void dynamicJDKTest(){RealSubject realSubject = new RealSubject();Subject proxyInstance = (Subject) Proxy.newProxyInstance(realSubject.getClass().getClassLoader(),realSubject.getClass().getInterfaces(),new DynamicProxyHandler(realSubject));proxyInstance.request();}
2. 基于 CGLIB 的动态代理

CGLIB(Code Generation Library)是一种用于在运行时生成类的库,它通过继承来创建代理对象。CGLIB 适用于代理类没有接口的情况。

使用步骤:
  1. 添加 CGLIB 依赖(如果是 Maven 项目,添加相关依赖)。
  2. 创建一个代理工厂
  3. 创建代理对象
  4. 调用方法

... 模版代码就不加了.网上都有。 

 

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词