美文网首页
Java中的代理模式

Java中的代理模式

作者: 王魔王 | 来源:发表于2018-12-09 15:09 被阅读0次

    动态代理:

    代理:本来应该自己做的事情,却请了别人来做,被请来的人就是代理对象
    例如:
    动态代理:在程序运行的过程中产生的这个对象
    在代理的过程中,可以在本类基础上添加新的功能,使其功能更强大
    注意,代理对象代理(执行)的是被代理对象的方法。即本来就是被代理对象拥有的方法,只是原来由被代理对象执行,现在换成了代理对象去执行,但是这个方法本来就是被代理者拥有的方法。
    jdk提供的代理只能针对接口做代理,我们有更强大的代理cglib

    java中的代理

    java在java.lang.reflect包下给我们提供了一个Proxy类和一个InvocationHandler接口,通过这个类和接口我们就可以生成动态代理对象。

    使用方式

    再次强调,java提供的动态代理只能针对接口做代理
    1.定义接口

    /**
     * 将要被代理的接口
     * eat为有参,无返回值的示例方法
     * sleep为无参,有返回值的示例方法
     */
    public interface Aniamal {
        void  eat(String food);
        boolean  sleep();
    }
    
    

    2.定义接口的实现类

    /**
     * 接口的具体实现类
     *
     */
    public class Person implements Aniamal {
        private static final String TAG = "Person";
        @Override
        public void eat(String food) {
            Log.d(TAG, "eat: 吃了"+food);
        }
    
        @Override
        public boolean sleep() {
            Log.d(TAG, "sleep: 睡的不错");
            return true;
        }
    }
    

    3.实现InvocationHandler类

    /**
     * 定义InvocationHandler的实现类
     *
     */
    public class PersonInvocationHandler implements InvocationHandler {
        private Aniamal aniamal;// 被代理对象
    
        //被代理对象要构造传参进来
        public PersonInvocationHandler(Aniamal aniamal) {
            this.aniamal = aniamal;
        }
    
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            //我们可以在方法执行前或者执行之后加入自己的逻辑
            //proxy为代理对象
            //这里的method就是将来我们调用的method
            //args就是我们传进来的参数
            //result是我们调用的method的返回值
            Object result = method.invoke(aniamal, args);
            return result;
        }
    }
    

    4.使用

     //创建被代理对象
            Person person = new Person();
            //创建InvocationHandler对象
            PersonInvocationHandler handler = new PersonInvocationHandler(person);
            //创建代理对象,将代理对象转换成被代理对象接口类型
            //创建方式一
            Aniamal proxyInstance =(Aniamal) Proxy.newProxyInstance(person.getClass().getClassLoader(),
                    person.getClass().getInterfaces(), handler);
      //创建方式二
     Aniamal proxyInstance =(Aniamal) Proxy.newProxyInstance(Aniamal.class.getClassLoader(),
                    Person.class.getInterfaces(), handler);
    
            //代理对象执行被代理对象的方法
            proxyInstance.eat("羊蝎子");
            boolean sleep = proxyInstance.sleep();
    
    下面我们看PersonInvocationHandler中的逻辑

    修改委托类的方法

    @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            //修改委托类的方法
            String name = method.getName();
            //如果发现让我吃羊蝎子,就强制改成吃烤鸭
            if (name.equals("eat") && args[0].equals("羊蝎子")) {
               return method.invoke(aniamal,"烤鸭");
            }
            return method.invoke(aniamal,args);
        }
    

    过滤委托类的方法

      @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            //过滤委托类的方法
            String name = method.getName();
            //如果发现要调用睡觉的方法,那么就不执行
            if (name.equals("sleep")) {
               return false;
            }
            return method.invoke(aniamal,args);
        }
    

    修改方法的返回值

    这个更容易,只要return自己想要的任何值就可以类

    动态代理作用

    1、不需要得到对应委托类的对象
    2、获取委托类的方法中的参数
    3、通过代理类对象,对委托类的方法进行过滤(修改)等
    4、修改委托类方法的返回值

    相关文章

      网友评论

          本文标题:Java中的代理模式

          本文链接:https://www.haomeiwen.com/subject/aeaucqtx.html