# Proxy

在不改变原始类代码的情况下，通过引入代理类来给原始类附加功能。

```java
public interface IUserController {
  UserVo login(String telephone, String password);
}

public class UserController implements IUserController {

  @Override
  public UserVo login(String telephone, String password) {
    ...
  }
}

public class UserControllerProxy implements IUserController {
  private UserController userController;

  public UserControllerProxy(UserController userController) {
    this.userController = userController;
  }

  @Override
  public UserVo login(String telephone, String password) {
    // do something
    
    // 委托
    UserVo userVo = userController.login(telephone, password);
    
    // do something
    
    return userVo;
  }
}
```

{% hint style="info" %}
若原始类没有定义接口，或者原始类是来自第三方库，代理类可以采用继承的形式。
{% endhint %}

动态代理：不事先为每个原始类编写代理类，而是在运行的时候，动态地创建代理类，然后在系统中用代理类替换掉原始类。Java 语言本身支持动态代理，底层依赖反射。

应用场景：

* 非功能性需求开发，比如监控、鉴权、事务等。
* RPC 框架。客户端使用 RPC 服务的时候，就像使用本地函数一样。
* 缓存。Spring AOP 定义哪些接口需要缓存，并设置响应的缓存策略。


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://yunzhao.gitbook.io/notes/computer-science/design-patterns/structural/proxy.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
