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();
    }
}
相关推荐
朦胧之3 小时前
AI 编程-老项目改造篇
java·前端·后端
程序猿大帅7 小时前
别再只当调包侠了:用 Spring AI 落地 Function Calling,我被大模型硬生生砸出了三个大坑
java
程序员晓琪8 小时前
约定大于配置:基于 Java 包名自动生成 API 版本路由的最佳实践
java·spring boot·后端
Flittly8 小时前
【AgentScope Java新手村系列】(11)中断与恢复
java·spring boot·spring
众少成多积小致巨9 小时前
JNI (Java Native Interface) 技术手册中文参考指南
android·java·c++
东坡白菜9 小时前
破局全栈:前端开发的Java入门实战记录—JPA(2)
java·后端
SimonKing15 小时前
艹,维护AI写的代码,我心态崩了......
java·后端·程序员
用户2986985301415 小时前
Java Word 文档样式进阶:段落与文本背景色设置完全指南
java·后端
小bo波1 天前
从"任意文件复制"深挖Java I/O:字符流与字节流的本质抉择
java·nio·io流·后端开发·文件复制
nanxun8862 天前
记一次诡异的 Docker 容器"串包"故障排查
java