JDK代理

先思考两个问题

为什么需要代理?

代理是什么样子?

===============================👇举个栗子👇===============================

鸡哥是一个大明星,唱跳rap篮球无所不精,有一天,很多真爱粉找到鸡哥说:咯咯,给我唱一首歌吧!

于是鸡哥开始着手准备,话筒,场地,门票,节目单等等,搞得鸡哥焦头烂额,唱歌也没有唱好。于是鸡哥说这样不行,我负责的太多了,搞得本职工作都搞不好。我非常心疼自家哥哥,于是告诉他,你去找一个经纪人吧,这样一来,话筒,场地,门票,节目单等等工作都交给了经纪人(方法增强),也就是代理,鸡哥只负责去唱跳rap篮球即可,也不需要来接待客户(中介隔离)。后来哥哥唱歌再没掉过链子。

综上所述:

为什么需要代理?答:对象自身方法过于复杂,可以使用代理来转移一些职责,换句话说,使用代理可以让对象的方法比之前更牛逼,而且不会侵入对象源代码。(这就是中介隔离和方法增强)

代理是什么样子?答:代理中是对象需要被代理的方法和其他一些实现。

那么引出一个新的问题:

代理是怎么知道他自己要代理哪些方法的?

换句话说,是怎么规范代理和被代理对象的方法的。

提取关键字,规范 。什么可以用来规范行为?当然是接口!

如果以上内容全部看懂了,那么就可以试着敲一敲下面的这个例子

可以把接口理解成鸡哥和经纪人签的合同,合同里写的是经纪人需要管理鸡哥的事情。

package com.apesource.dynamic;

public interface Singer {
    String sing();
    void dance();
}

鸡哥本体,被代理对象

package com.apesource.dynamic;

public class ChickenSingerImpl implements Singer{
    @Override
    public String sing() {
        System.out.println("只因你太美~~~");
        return "感谢聆听";
    }

    @Override
    public void dance() {
        System.out.println("篮球舞");
    }
}

经纪人,也就是代理对象

package com.apesource.dynamic;

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

public class JinJiRenProxyUtil {
    public static Object createProxy(final Object obj) {
        /**
         * 参数一:用于指定用哪个类加载器,去加载生成的代理类
         * 参数二:指定接口,这些接口用于指定生成的代理长什么,也就是有哪些方法
         * 参数三:用来指定生成的代理对象要干什么事情
         */
        return Proxy.newProxyInstance(obj.getClass().getClassLoader(),
                obj.getClass().getInterfaces(),
                new InvocationHandler() {
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        Object res = null;
                        if (method.getName().equals("sing")) {
                            System.out.println("准备话筒,收钱");
                            res = method.invoke(singer, args);
                            System.out.println("唱完了,准备晚会");
                        } else if (method.getName().equals("dance")) {
                            System.out.println("准备场地收钱");
                            method.invoke(singer, args);
                        }
                        return res;
                    }
                });
    }
}

粉丝(测试类,调用者)

package com.apesource.dynamic;

public class TestClient {
    public static void main(String[] args) {
        //        不能找明星 直接找经纪人
        Singer proxy = (Singer) JinJiRenProxyUtil.createProxy(new ChickenSingerImpl());
        System.out.println(proxy.sing());
    }
}

代码就是这么写,很规范,主要是这种思想:对纵向代码的横向扩展需要理解,多想着这个例子,敲两遍就拿下了。

  • 19
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值