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();
    }
}
相关推荐
岁岁种桃花儿几秒前
SpringCloud从入门到上天:Nacos做微服务注册中心
java·spring cloud·微服务
jdyzzy1 分钟前
什么是 JIT 精益生产模式?它与传统的生产管控方式有何不同?
java·大数据·人工智能·jit
Chasmれ6 分钟前
Spring Boot 1.x(基于Spring 4)中使用Java 8实现Token
java·spring boot·spring
froginwe117 分钟前
Python 条件语句
开发语言
汤姆yu8 分钟前
2026基于springboot的在线招聘系统
java·spring boot·后端
七夜zippoe10 分钟前
Python统计分析实战:从描述统计到假设检验的完整指南
开发语言·python·统计分析·置信区间·概率分布
2601_9491465317 分钟前
Python语音通知API示例代码汇总:基于Requests库的语音接口调用实战
开发语言·python
3GPP仿真实验室23 分钟前
【Matlab源码】6G候选波形:OFDM-IM 索引调制仿真平台
开发语言·matlab
计算机学姐33 分钟前
基于SpringBoot的校园社团管理系统
java·vue.js·spring boot·后端·spring·信息可视化·推荐算法
Coder_Boy_39 分钟前
基于SpringAI的在线考试系统-企业级教育考试系统核心架构(完善版)
开发语言·人工智能·spring boot·python·架构·领域驱动