Java——动态代理(1/2)-动态代理设计模式介绍、准备工作、代码实现(如何创建代理对象)

目录

模式介绍

准备工作

如何创建代理对象 

代码实现

参数三

ProxyUtil类

Test 


模式介绍

程序为什么需要代理?

场景:一位歌手需要进行演出,具有以下两个方法:

唱歌(){

        准备话筒,收钱

        真正开始唱歌

}

跳舞(){

        准备话筒,收钱

        真正开始跳舞

}

歌手进行的工作是唱歌和跳舞,然而那些准备工作不用歌手自己来做,而是由经纪人来做,这就是代理。

代理是什么样的?

对象如果嫌身上干的事太多的话,可以通过代理来转移部分职责。

对象有什么方法想被代理,代理就一定要有对应的方法。

如何知道要派有唱歌、跳舞方法的代理呢?

  • 通过接口

也就是经纪公司给出接口,决定要派出什么样的经纪人给歌手

public interface Star{

        sing方法

        dance方法

}

 

准备工作

public interface Star {
    String sing(String name);
    void dance();
}
public class BigStar implements Star{
    private String name;
    public BigStar(String name){
        this.name = name;
    }
    @Override
    public String sing(String name) {
        System.out.println(this.name + "正在唱:" + name);
        return "谢谢!谢谢!";
    }

    @Override
    public void dance() {
        System.out.println(this.name + "正在优雅地跳舞~~");
    }
}

如何创建代理对象 

  • java.lang.reflect.Proxy类:提供了为对象产生代理对象的方法:

public static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h)

  • 参数一:用于指定用哪个类加载器,去加载生成的代理类
  • 参数二:指定接口,这些接口用于指定生成的代理长什么,也就是有哪些方法
  • 参数三:用来指定生成的代理对象要干什么事情

代码实现

参数三

参数三有点特殊,它是一个匿名内部类,类中重写的方法是一个回调方法:

我们逐个讲解一下:

 

ProxyUtil类

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

public class ProxyUtil {
    public static Star createProxy(BigStar bigStar){
        /*
        public static Object newProxyInstance(ClassLoader loader,
                                            Class<?>[] interfaces,
                                            InvocationHandler h)
        参数一:用于指定用哪个类加载器,去加载生成的代理类
        参数二:指定接口,这些接口用于指定生成的代理长什么,也就是有哪些方法
        参数三:用来指定生成的代理对象要干什么事情
         */

        // Star starProxy = ProxyUtil.createProxy(s);
        // starProxy.sing("小幸运")
        // starProxy.dance();
        Star starProxy = (Star) Proxy.newProxyInstance(ProxyUtil.class.getClassLoader(),
                new Class[]{Star.class}, new InvocationHandler() {
                    @Override   //回调方法
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        //代理对象要做的事情,会在这里写代码
                        if(method.getName().equals("sing")){
                            System.out.println("准备话筒,收钱20万");
                        }else if(method.getName().equals("dance")){
                            System.out.println("准备场地,收钱1000万");
                        }
                        return method.invoke(bigStar,args);
                    }
                });
        return starProxy;
    }
}

Test 

public class Test {
    public static void main(String[] args) {
        BigStar s = new BigStar("希林");
        Star starProxy = ProxyUtil.createProxy(s);

        String rs = starProxy.sing("小幸运");
        System.out.println(rs);
        starProxy.dance();
    }
}

运行结果:


END


学习自:黑马程序员——Java课程

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值