> For the complete documentation index, see [llms.txt](https://luckycurvec.gitbook.io/java-knowledge-architecture/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://luckycurvec.gitbook.io/java-knowledge-architecture/zhi-shi-dian-hui-zong-4/dai-li-ji-shu.md).

# 代理技术知识点汇总

## 静态代理

按照自己理解写的，结合了《Spring揭秘》中作者对代理的理解。建议先看下面的动态代理的例子，就是按照下面例子改编的

等价的静态代理的例子为：

```java
//针对Hello的静态代理
public class StaticProxy {
    private final Hello hello;

    public StaticProxy(Hello hello) {
        this.hello = hello;
    }

    //代理Hello实例化对象的hello方法
    public void hello() {
        System.out.println("Before Method");
        hello.hello();
        System.out.println("After Method");
    }
}
```

虽然对所有Hello接口的实现类都有效，但是如果存在很多个接口的实现类都需要相同的需求，依旧需要创建很多个这样的Proxy出来，非常的不方便。

## 动态代理

使用动态代理需要该类需要代理的方法是重写于一个接口的，代码如下：

```java
public interface Hello {
    void hello();
}
```

实现类（直接使用了lambda表达式简写了匿名内部类）：

```java
Hello hello = () -> System.out.println("hello Method");
```

简单输出一句：hello Method

一种代理模式演示（在方法调用前后进行输出）

```java
public class AroundProxy implements InvocationHandler {

    private final Object obj;

    public AroundProxy(Object obj) {
        this.obj = obj;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        //做AOP切面
        System.out.println("Before Method");
        Object o = method.invoke(obj, args);
        System.out.println("After Method");
        return o;
    }
}
```

感觉这种就非常好理解了，运行的逻辑都被封装在了InvocationHandler的invoke方法里了

使用的时候：

```java
Hello hello = () -> System.out.println("hello Method");
//进行代理
AroundProxy proxy = new AroundProxy(hello);
//获取代理得到的通用接口
Hello o = (Hello) Proxy.newProxyInstance(Hello.class.getClassLoader(), new Class[]{Hello.class}, proxy);
//好奇，输出了o的类型
System.out.println(o.getClass());
//使用接口
o.hello();
```

输出如下：

```
class com.sun.proxy.$Proxy0
Before Method
hello Method
After Method
```
