Java动态代理示例代码

package proxy;

public class BigStar implements Star {

    private String name;

    public BigStar(String name) {
        this.name = name;
    }

    @Override
    //明星只负责演唱,至于准备工作和扫尾工作交给代理完成
    public String sing(String singName) {
        System.out.println(this.name + "正在演唱:" + singName);
        return "演出结束,谢谢大家";
    }

    @Override
    public void dance() {
        System.out.println(this.name + "正在表演舞蹈...");
    }

    public String getName() {
        return name;
    }
}

1.Star接口

package proxy;

public class BigStar implements Star {

    private String name;

    public BigStar(String name) {
        this.name = name;
    }

    @Override
    //明星只负责演唱,至于准备工作和扫尾工作交给代理完成
    public String sing(String singName) {
        System.out.println(this.name + "正在演唱:" + singName);
        return "演出结束,谢谢大家";
    }

    @Override
    public void dance() {
        System.out.println(this.name + "正在表演舞蹈...");
    }

    public String getName() {
        return name;
    }
}

明星类,实现Star接口。明星类只专注业务的实现,至于其他无关工作(如这里的准备和收尾工作)应该交给代理类完成。

package proxy;

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

public class ProxyUtil {

    //为哪个明星生成代理
    //注意,由于外部找的都是代理对象,而代理对象才去调用BigStar底层的方法。
    //因此,生成的代理对象应该和BigStar一样都有共同的方法sing和dance
    //
    public static Star createProxy(BigStar bigStar) {
        //第一个参数:用于指定一个类加载器
        //第二个参数:指定生成的代理对象应该有哪些方法,传入一个接口数组
        //第三个参数:用来指定代理对象具体应该做什么事
        Star star = (Star) Proxy.newProxyInstance(ProxyUtil.class.getClassLoader(),
                new Class[]{Star.class},
                new InvocationHandler() {
                    //这个invoke方法是一个回调方法
                    //当Star starProxy = ProxyUtil.createProxy(s); 创建一个代理对象时
                    //starProxy.sing("好运来") starProxy.dance() 代理对象调用sing方法或者dance方法时,
                    //这两个方法就会回调invoke方法!
                    @Override
                    //第一个参数:表示被代理的对象,也就是这里的bigStar对象
                    //第二个参数:表示回调这个invoke的方法(sing、dance)
                    //第三个参数:表示回调invoke方法中的参数(比如说sing(String sing) 中的singName)
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        Object o = new Object();
                        if (method.getName().equals("sing")) {
                            System.out.println("正在准备唱歌的场地和话筒...");
                            //调用被代理对象的方法
                            o = method.invoke(bigStar, args);
                            System.out.println("演唱会结束,工作人员正在清理现场...");
                        } else if (method.getName().equals("dance")) {
                            System.out.println("正在准备舞台");
                            method.invoke(bigStar, args);
                            System.out.println(bigStar.getName() + "跳舞结束,工作人员正在清理现场...");
                        }
                        return o;
                    }
                }
        );
        return star;
    }
}

代理类,注意这里采用匿名内部类的形式重写invoke方法。

package proxy;

public class Test {

    public static void main(String[] args) {

        BigStar bigStar = new BigStar("周杰伦");
        Star proxy = ProxyUtil.createProxy(bigStar);
        System.out.println(proxy.sing("双截棍"));
        proxy.dance();
    }
}

测试类

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值