今天说一下这个Java基础(九) 动态代理

代理分为静态代理和动态代理。

动态代理分为CGLIB代理和jdk动态代理,这里主要讲jdk动态代理。

静态代理

为每个目标类设置一个代理类,实现代理类的方法和接口,同时新增其他逻辑。

静态代理类 = 目标类 + 增强方法。

缺点:为每个类都要写自己的代理类,麻烦。而且多了之后业务逻辑非常非常复杂

动态代理

因为静态代理的缺点,动态代理的目的就是,少写或者不写代理类,却能完成代理功能。

原理:

关于对象的创建过程:

1,classloader加载类文件到内容

2,执行new,申请新的内存空间

3,调用构造器,创建空白对象

4,使用父类构造器(双亲委贷机制)

5,执行构造器内容

那么可以明白,创建一个对象的关键是,得到它的class文件然后进行调用。

所以动态代理,可以通过调用class类文件,然后通过反射机制生成相对应的代理类或者代理对象。

jdk动态代理:

因为我们不写代理类,但是我们需要构造器,字段啥的,这些数据要去哪里获取呢?这里可以通过代理类和目标类实现同一个的接口来完成,这样我们就可以通过接口来获取目标类的类信息。

jdk动态代理就是基于这个思想,也就是说jdk动态代理是基于接口实现的

实现

但是接口是不可以生成对象的,那怎么办呢?

jdk提供了两个对象,一个是invocationhandler接口和proxy类,两个类相互配合。

invocationhandler

通过实现这个接口表示生成代理类

public class RpcClientProxy implements InvocationHandler {
    private String host;
    private int port;

    public RpcClientProxy(String host, int port) {
        this.host = host;
        this.port = port;
    }

    @SuppressWarnings("unchecked")
    public <T> T getProxy(Class<T> clazz) {
        return (T) Proxy.newProxyInstance(clazz.getClassLoader(), new Class<?>[]{clazz}, this);
    }
}

比如例子中rpcclientproxy就是代理类,他不需要实现目标类的东西了,只需要增强方法。

getProxy方法是用于生成代理对象的,多封装一层,方便。

实现invocationhandler接口,需要实现invoke的方法。

invoke方法用于表示代理对象的方法被调用时的动作。

@Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        RpcRequest rpcRequest = RpcRequest.builder()
                .interfaceName(method.getDeclaringClass().getName())
                .methodName(method.getName())
                .parameters(args)
                .paramTypes(method.getParameterTypes())
                .build();
        RpcClient rpcClient = new RpcClient();
        return ((RpcResponse) rpcClient.sendRequest(rpcRequest, host, port)).getData();
    }

相当于是增强方法。

proxy

用于生成代理对象或者代理类

getProxyClass(),生成代理类

Proxy.newProxyInstance(),生成代理实例,一般都用这个,比如类中的getProxy。

正文完