Java静态代理和动态代理(JDK)的简单实现

发布时间:2024年01月02日

1. 静态代理

静态代理模拟角色分析:

  • 抽象角色 : 一般使用接口或者抽象类来实现
  • 真实角色 : 被代理的角色
  • 代理角色 : 代理真实角色 ; 代理真实角色后 , 一般会做一些附属的操作
  • 客户: 使用代理角色来进行一些操作

代码模拟:

Rent.java——>抽象角色

/**
 * Description: 租房
 */
public interface Rent {

    public void rent();
}

Host.java——>真实角色

/**
 * Description: 房东
 */
public class Host implements Rent {

    @Override
    public void rent() {
        System.out.println("房东要出租房子!!!");
    }
}

Proxy.java——>代理角色

/**
 * Description: 静态代理角色
 */
public class Proxy implements Rent{

    private Host host;

    public Proxy() {
    }

    public Proxy(Host host) {
        this.host = host;
    }

    @Override
    public void rent() {
        lookHouse();

        host.rent();

        charge();
    }

    // 看房
    public void lookHouse() {
        System.out.println("中介带你看房!");
    }

    // 收中介费
    public void charge() {
        System.out.println("中介收取中介费!");
    }
}

Client.java——>客户角色

/**
 * Description: 租客
 */
public class Client {

    public static void main(String[] args) {
        Host host = new Host();

        /*// 正常租房(自己找房东)
        host.rent();*/

        // 代理租房, 一般会有一些附属操作
        Proxy proxy = new Proxy(host);
        // 直接找中介租房
        proxy.rent();
    }
}

分析:在这个过程中,你直接接触的就是中介,就如同现实生活中的样子,你看不到房东,但是你依旧通过代理租到了房东的房子,这就是所谓的代理模式,程序源自于生活,所以学编程的人,一般能够更加抽象的看待生活中发生的事情。

静态代理的优点

  • 可以使得我们的真实角色更加纯粹 . 不再去关注一些公共的事情
  • 公共的业务由代理来完成 . 实现了业务的分工
  • 公共业务发生扩展时变得更加集中和方便

静态代理的缺点

  • 类多了——>代理类多了 ——>工作量变大了. 开发效率降低 .

我们想要静态代理的好处,又不想要静态代理的缺点,所以 , 就有了动态代理 !

2. 动态代理

我们在不改变原来的代码的情况下,实现了对原有功能的增强,这是AOP中核心的思想

  • 动态代理的角色和静态代理的一样
  • 动态代理的代理类是动态生成的,静态代理的代理类是我们提前写好的
  • 动态代理分为两类 : 一类是基于接口动态代理 , 一类是基于类的动态代理
    • 基于接口的动态代理----JDK动态代理
    • 基于类的动态代理–cglib
    • 现在用的比较多的是 javasist 来生成动态代理

JDK动态代理:

  • Interface InvocationHandler 【调用处理程序】

  • Class Proxy 【代理】

Proxy代理类下的 newProxyInstance 方法:

在这里插入图片描述

代码模拟:

Rent.java——>抽象角色

/**
 * Description: 租房
 */
public interface Rent {

    public void rent();
}

Host.java——>真实角色

/**
 * Description: 房东
 */
public class Host implements Rent{

    @Override
    public void rent() {
        System.out.println("房东要出租房子!!!");
    }
}

Proxy.java——>代理角色

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * Description: 调用处理程序,自动生成代理类
 */
public class ProxyInvocationHandler implements InvocationHandler {

    // 被代理的接口
    private Object target;

    public void setTarget(Object target) {
        this.target = target;
    }

    // 生成代理类,重点是第二个参数,获取要代理的抽象角色!之前都是一个角色,现在可以代理一类角色
    public Object getProxy() {
        return Proxy.newProxyInstance(this.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
    }

    // proxy : 代理类 method : 代理类的调用处理程序的方法对象. 
    // 处理代理实例上的方法调用,并返回结果
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        // 动态代理的本质,就是使用反射机制实现
//        lookHouse();
        Object result = method.invoke(target, args);
//        charge();
        return result;
    }

    /*// 看房
    public void lookHouse() {
        System.out.println("中介带你看房!");
    }

    // 收中介费
    public void charge() {
        System.out.println("中介收取中介费!");
    }*/
}

Client.java——>客户角色

/**
 * Description: 租客
 */
public class Client {

    public static void main(String[] args) {
        // 真实角色
        Host host = new Host();

        // 代理实例的调用处理程序
        ProxyInvocationHandler proxyInvocationHandler = new ProxyInvocationHandler();
        // 将真实角色放置进去
        proxyInvocationHandler.setTarget(host);
        // 动态生成对应的代理类
        Rent proxy = (Rent) proxyInvocationHandler.getProxy();
        proxy.rent();
    }
}

核心:一个动态代理 , 一般代理某一类业务 , 一个动态代理可以代理多个类,代理的是接口

优点:

  • 可以使得我们的真实角色更加纯粹 . 不再去关注一些公共的事情
  • 公共的业务由代理来完成 . 实现了业务的分工
  • 公共业务发生扩展时变得更加集中和方便
  • 一个动态代理 , 一般代理某一类业务
  • 一个动态代理可以代理多个类,代理的是接口
文章来源:https://blog.csdn.net/weixin_52164430/article/details/135330437
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。