代理模式使用

场景:不直接访问某个对象时,可设置一个代理对象来间接访问,为了保证代码的透明度,委托对象与代理对象需要实现相同的接口。

静态代理和动态代理;代理类和被代理类都要继承或实现相同的接口或方法;代理类通过被代理类的引用来调用具体的业务逻辑。

Retrofit的create就是使用的动态代理模式。

具体实现

功能接口

    interface Person {
        void say();
        void func();
    }

被代理类

    class XiaoMing implements Person {
        @Override
        public void say() {
            System.out.println("小明");
        }

        @Override
        public void func() {
            System.out.println("我会跑步");
        }
    }
    class XiaoLi implements Person {
        @Override
        public void say() {
            System.out.println("小李");
        }

        @Override
        public void func() {
            System.out.println("我会唱歌");
        }
    }
    class XiaoWang implements Person {
        @Override
        public void say() {
            System.out.println("小王");
        }

        @Override
        public void func() {
            System.out.println("我会游泳");
        }
    }

使用静态代理的方式

(1)实例化代理对象传入代理类

    //代理类
    public class PersonProxy implements Person {
        private Person person;

        public PersonProxy (Person person) {
            this.person = person;
        }

        //更改代理对象
        public void setPerson(Person person) {
            this.person = person;
        }

        @Override
        public void say() {
            if(person != null){
                person.say();
            }
        }

        @Override
        public void func() {
            if(person != null){
                person.func();
            }
        }
    }

    //使用
    PersonProxy proxy = new PersonProxy(new XiaoLi());
    proxy.say();
    proxy.func();
    proxy.setPerson(new XiaoWang());
    proxy.say();
    proxy.func();
    
    //输出
    小李
    我会唱歌
    小王
    我会游泳

(2)利用java反射创建被代理类对象

    //代理类
    public class PersonProxy implements Person {
        private Person person;

        //传入被代理类的全类名
        public PersonProxy(String clsStr) {
            try {
                this.person = (Person) Class.forName(clsStr).newInstance();
            } catch (Exception e) {
                e.printStackTrace();
                System.out.println(e.getMessage());
            }
        }

        //传入被代理类
        public PersonProxy(Class<? extends Person> cls) {
            try {
                this.person = cls.newInstance();
            } catch (InstantiationException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void say() {
            if(person != null) {
                person.say();
            }
        }

        @Override
        public void func() {
            if(person != null) {
                person.func();
            }
        }
    }


    //使用
    PersonProxy proxy1 = new PersonProxy(XiaoMing.class);
    proxy1.say();
    proxy1.func();
    //我这里XiaoWang的JavaBean放在com.demo.test目录下
    PersonProxy proxy2 = new PersonProxy("com.demo.test.XiaoWang");
    proxy2.say();
    proxy2.func();
    
    //输出
    System.out: 小明
    System.out: 我会跑步
    System.out: 小王
    System.out: 我会游泳

(3)使用注解指明代理对象

    public static final int XIAOMING = 1;
    public static final int XIAOLI = 2;
    public static final int XIAOWANG = 3;

    @Retention(RetentionPolicy.SOURCE)
    @IntDef({XIAOMING, XIAOLI, XIAOWANG})
    public @interface PersonAnno {}

    //代理类
    public class PersonProxy implements Person {
        private Person person;
        //通过注解来指定代理对象
        public PersonProxy (@PersonAnno int type) {
            if (type == 1) {
                person = new XiaoMing();
            } else if (type == 2) {
                person= new XiaoLi();
            } else {
                person= new XiaoWang();
            }
        }

        @Override
        public void say() {
            if(person != null){
                person.say();
            }
        }

        @Override
        public void func() {
            if(person != null){
                person.func();
            }
        }
    }

    //使用
    PersonProxy proxy = new PersonProxy(XIAOMING);
    proxy.say();
    proxy.func();
   
    //输出
    System.out: 小明
    System.out: 我会跑步

使用动态代理的方式

(1)传入被代理类的实例化对象

    //动态代理类
    public class PersonProxy implements InvocationHandler {
        Object object;
        public PersonProxy(Object object){
            this.object = object;
        }

        public void setObject(Object object) {
            this.object = object;
        }

        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            System.out.println(object.getClass().getSimpleName() + "的" + method.getName() + "调用前");
            method.invoke(object, args);//代理类方法调用时的切面
            System.out.println(object.getClass().getSimpleName() + "的" + method.getName() + "调用后");
            return null;
        }
    }


    //使用
    Person xiaoMing = new XiaoMing();
    PersonProxy proxy = new PersonProxy(xiaoMing);
    Person person = (Person) Proxy.newProxyInstance(xiaoMing.getClass().getClassLoader(), xiaoMing.getClass().getInterfaces(), proxy);
    person.say();
    person.func();
    System.out.println("--------------------------------");
    Person xiaoLi = new XiaoLi();
    proxy.setObject(xiaoLi);
    Person person2 = (Person) Proxy.newProxyInstance(xiaoLi.getClass().getClassLoader(), xiaoLi.getClass().getInterfaces(), proxy);
    person2.say();
    person2.func();

    //输出
    System.out: XiaoMing的say调用前
    System.out: 小明
    System.out: XiaoMing的say调用后
    System.out: XiaoMing的func调用前
    System.out: 我会跑步
    System.out: XiaoMing的func调用后
    System.out: --------------------------------
    System.out: XiaoLi的say调用前
    System.out: 小李
    System.out: XiaoLi的say调用后
    System.out: XiaoLi的func调用前
    System.out: 我会唱歌
    System.out: XiaoLi的func调用后

(2)传入被代理类

    public class PersonProxy implements InvocationHandler {
        Person person;
        
        public PersonProxy(Class<? extends Person> cls){
            try {
                this.person = cls.newInstance();
            } catch (InstantiationException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }

        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            System.out.println(person.getClass().getSimpleName() + "的" + method.getName() + "调用前");
            method.invoke(person, args);//代理类方法调用时的切面
            System.out.println(person.getClass().getSimpleName() + "的" + method.getName() + "调用后");
            return null;
        }
    }

    //使用
    Class cls = XiaoMing.class;
    PersonProxy proxy = new PersonProxy(cls);
    Person person = (Person) Proxy.newProxyInstance(cls.getClassLoader(), cls.getInterfaces(), proxy);
    person.say();
    person.func();

    //输出
    System.out: XiaoMing的say调用前
    System.out: 小明
    System.out: XiaoMing的say调用后
    System.out: XiaoMing的func调用前
    System.out: 我会跑步
    System.out: XiaoMing的func调用后

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值