动态代理(Proxy实现)

上次的静态代理增强方法全是自己手动写出来的,如果有许多方法,都需要自己一个一个写,显然太麻烦了,这时就可以用到动态代理,制定规则,所有方法统一实现,这次先用proxy实现

除了静态代理类方法别的都一样

Singer接口

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

目标类

public class ZStar implements Singer{
    @Override
    public void sing() {
        System.out.println("我在唱歌.......");
    }
    @Override
    public void dance() {
        System.out.println("我在跳舞......");
    }
}

方法规则 StarRulerProxy

public class StarRulerProxy implements InvocationHandler {
    private  Singer singer;//需要实现的接口类
    public StarRulerProxy(Singer singer) {
        this.singer = singer;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("经纪人商量合同");
        method.invoke(singer,args);
        System.out.println("经纪人收钱");
        return null;
    }

}

查看InvocationHandler接口源码中的方法,可以看见只有invoke接口方法,所以只需要实现invoke方法就行,invoke不需要我们用代码调用,他自己会调用

 

// 其中invoke的传参含义

Object proxy :构造方法中singer指代的对象
Method method 是在运行时对象运行的方法,就比如我主方法中调用dance方法,传入的就是dance

Object[] args:是指在在调用方法时传入的参数,由于我在写接口是都未添加传参,所以在这不传值为null

主方法运行

public class Test {
    public static void main(String[] args) {
        StarRulerProxy starProxy = new StarRulerProxy(new ZStar());
        Object test = Proxy.newProxyInstance(ZStar.class.getClassLoader(),ZStar.class.getInterfaces(),starProxy);
        Singer star = (Singer) test;
        star.dance();//我跳舞
        System.out.println();
        star.sing();//我唱歌
    }

}

其中newProxyInstance各个传参含义,首先看源码

 其中ClassLoader loader:指定类加载器,我写的例子中很明显是Ztar类的加载器

Class<?>[] interfaces :获取类继承的接口当然也可以用  new Class[]{Singer.class} 代替ZStar.class.getInterfaces() 效果一样。

InvocationHandler h:说明你想要使用哪个规则,如果说你有多个RulerProxy类,你可以指定其中一个。

运行结果:

 这是所有方法按统一规则执行的,但如果说我有其中一个方法,不想按这个规则来了,我们可以用if来判断

public class StarRulerProxy implements InvocationHandler {
    private  Singer singer;//需要实现的接口类
    public StarRulerProxy(Singer singer) {
        this.singer = singer;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        if(method.getName().equals("sing")){
            System.out.println("唱歌不要钱");
            method.invoke(singer,args);
            System.out.println("经纪人不收钱");
        }else{
            System.out.println("经纪人商量合同");
            method.invoke(singer,args);
            System.out.println("经纪人收钱");
        }
        return null;
    }

}

运行结果

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值