java代理简单理解

一、什么是代理

举例说明:当我想买一台电脑,国内太贵了。委托好友A在国外帮忙买。

这个情节中我要实现的动作和好友实现的动作一样,都是买电脑。好友帮我完成了这个动作,这就是代理。

类A和类B都实现一个interface接口C,C规定了A和B要完成的动作。借助B类实现A类完成接口中的动作。

1.使用代理的场景?

(1)功能增强:B完成接口中的动作之余还做了别的事情

(2)控制访问:B不让A访问到目标类,只有通过B这个媒介,A才能访问

二、静态代理

静态代理就是:自己写类实现代理。

思路:一个接口C,一个代理类B,一个被代理类A。两个类都实现接口C,在B实现接口中的方法时调用A对象方法。

接口C:

复制代码
public interface Singer {
    void singing();
    int dance();
}

被代理类A

复制代码
public class Cai implements Singer {
    @Override
    public void singing() {
        System.out.println("cai 唱歌");
    }

    @Override
    public int dance() {
        System.out.println("tiaowu");
        return 0;
    }
}

代理类A

复制代码
public class Caidaili implements  Singer{
    private Singer cai = new Cai();
    @Override
    public void singing() {
        System.out.println("先收钱");
        cai.singing();
    }

    @Override
    public int dance() {
        System.out.println("先收钱");
        cai.dance();
        return 0;
    }
}

测试

复制代码
public class Main {
    public static void main(String[] args) {
        Singer singer = new Caidaili();
        singer.singing();
        singer.dance();
    }
}

静态代理的局限性:如果被代理类太多了,每个被代理类都要有一个代理。这样写的代理类就太多了。因此引入动态代理,动态决定被代理类。

三、动态代理

动态代理就是不需要自己写代理类了,通过反射或者继承实现。动态代理有两种模式:

(1)jdk动态代理

通过反射类实现代理

核心代码:

Proxy.newProxyInstance(被代理的类的类加载器,被代理类实现的接口,实现InvocationHandler的类对象)

返回:代理类对象

参数列表中:InvocationHandler接口(函数式接口)重写了invoke方法,重写代码中的核心:

复制代码
被代理对象.方法()

method.invoke(接口对象,参数)                  //表示调用这个接口中的方法

实例:

接口

复制代码
public interface Singer {
    void dance();
    int singing();

}

被代理类

复制代码
public class Cai implements Singer {
    @Override
    public void dance() {
        System.out.println("Cai 在跳舞");
    }

    @Override
    public int singing() {
        System.out.println("Cai 在唱歌");
        return 0;
    }
}

jdk动态代理实现

复制代码
public class Test1 {
    public static void main(String[] args) {
        Cai cai =new Cai();
//        Ruler ruler = new Ruler(cai);
        //构建了 以原被代理类为基准的代理类的一个对象
        // o 已经等同于 Student s = new Student(); 这个s了
        Object o = Proxy.newProxyInstance(Cai.class.getClassLoader(), new Class[]{Singer.class}, (proxy, method, args1) -> {
            System.out.println(proxy.getClass().toString());
            System.out.println("先收钱");
            Object returnVal = method.invoke(cai, args1);
            System.out.println("asdfasdf");
            return returnVal;
        });
        System.err.println(o.getClass().toString());
        if(o instanceof Singer){
            Singer singer =  (Singer)o;
            singer.dance();
            singer.singing();
            singer.toString();
        }
    }
}

(2)cglib动态代理

不写接口,通过继承关系重写方法实现代理

示例:

被代理类:

复制代码
public class Singer {
    public void dance(){
        System.out.println("tiaowu");
    }
    public int singing(){
        System.out.println("changge");
        return 100;
    }
}

代理类:

复制代码
public class SingerSub extends Singer {
    @Override
    public void dance() {
        System.out.println("shouqian");
        super.dance();

    }

    @Override
    public int singing() {
        System.out.println("shouqian");
        return super.singing();
    }
}

测试:

复制代码
public class Main {
    public static void main(String[] args) {
        Singer singer = new SingerSub();
        singer.singing();
        singer.dance();
    }
}
相关推荐
TNTLWT几秒前
Qt功能区:Ribbon使用
开发语言·qt·ribbon
正在走向自律5 分钟前
2025年、2024年最新版IntelliJ IDEA下载安装过程(含Java环境搭建+Maven下载及配置)
java·jvm·jdk·maven·intellij-idea
不会就选C.5 分钟前
【开源分享】健康饮食管理系统(双端+论文)
java·spring boot·开源·毕业设计
永远有多远.6 分钟前
【高频面试题】LRU缓存
java·缓存·面试
Ten peaches7 分钟前
Selenium-Java版(环境安装)
java·前端·selenium·自动化
Ronin30513 分钟前
【C++】18.二叉搜索树
开发语言·数据结构·c++
Susea&15 分钟前
初始C++:类和对象(中)
c语言·开发语言·c++
编程、小哥哥24 分钟前
Java求职者面试:从Spring Boot到微服务的技术点解析
java·spring boot·redis·微服务·spring security·高并发·面试题
山海不说话30 分钟前
PyGame游戏开发(入门知识+组件拆分+历史存档/回放+人机策略)
开发语言·python·pygame
明月看潮生31 分钟前
青少年编程与数学 02-019 Rust 编程基础 11课题、类型系统
开发语言·青少年编程·rust·数据类型·编程与数学