美文网首页
Android中使用Java的动态代理

Android中使用Java的动态代理

作者: 沙夏cc | 来源:发表于2018-11-26 15:22 被阅读0次

    同事写一个功能的时候,使用了Java的动态代理,虽然我不赞同他在实现那个功能时使用这项技术,但是不能忽略动态代理在Android中的作用的。

    比如很多插件化框架就是以动态代理为原理的。Android插件化原理解析——Hook机制之动态代理

    所以这里简单介绍下java代理相关的知识。

    1.Java的代理模式

    定义:为其他对象提供一种代理以控制对这个对象的访问

    说白了就是在一个对象不好修改时,可以通过new一个新的代理对象对他进行控制,并且可以很容易的加入一些新的方法和特性。

    Java的代理技术一般分为三种,静态代理、动态代理及Cglib代理。

    2.静态代理

    静态代理比较简单,看下下面的代码就很好理解了。

    //定义一个接口
    public interface Interface {
        void doSomething();
    
        void somethingElse(String args);
    }
    
    //定义一个被代理的类
    public class RealObject implements Interface {
    
        @Override
        public void doSomething() {
            System.out.println("doSomething");
        }
    
        @Override
        public void somethingElse(String args) {
            System.out.println("somethingElse" + args);
        }
    }
    
    
    //新的代理的类
    public class SimpleProxy implements Interface {
        //被代理的类作为成员变量
        private Interface proxied;
        //构造方法中传入
        public SimpleProxy(Interface proxied) {
            this.proxied = proxied;
        }
    
        //实现接口
        @Override
        public void doSomething() {
            System.out.println("SimpleProxy doSomething");
            proxied.doSomething();
    
        }
    
        @Override
        public void somethingElse(String args) {
            System.out.println("SimpleProxy somethingElse" + args);
            proxied.somethingElse(args);
        }
    }
    
    //测试一下
    public class SimpleProxyDemo {
    
        public static void consumer(Interface iface) {
            iface.doSomething();
            iface.somethingElse(":jyu");
        }
    
        public static void main(String[] args) {
            consumer(new RealObject());
            consumer(new SimpleProxy(new RealObject()));
        }
    }
    
    

    输出:

    doSomething
    somethingElse:jyu
    SimpleProxy doSomething
    doSomething
    SimpleProxy somethingElse:jyu
    somethingElse:jyu
    

    动态代理

    动态代理也叫做JDK代理、接口代理。不需要实现目标对象的接口。生成代理对象,使用的是Java的API,动态的在内存中构件代理对象(这需要我们指定创建代理对象/目标对象的接口的类型)。

    看下下面的例子。还是使用上面的Interface接口,和RealObject类。

    //实现InvocationHandler接口
    public class DynamicProxyHandler implements InvocationHandler {
    
        private Object proxied;
    
        public DynamicProxyHandler(Object proxied) {
            this.proxied = proxied;
        }
    
        //覆写invoke方法
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            System.out.println("*** proxy:" 
            + proxy.getClass() + ",\nmethod:" 
            + method + ",\nargs:" + args);
            if (args != null) {
                for (Object arg : args) {
                    System.out.println("   " + arg);
                }
            }
            return method.invoke(proxied, args);
        }
    }
    
    //测试一下
    public class SimpleDynamicProxy {
    
        public static void consumer(Interface iface) {
            iface.doSomething();
            iface.somethingElse(" jyu");
        }
    
        public static void main(String[] args) {
            RealObject real = new RealObject();
            consumer(real);
    
            Interface proxy = (Interface) Proxy.newProxyInstance(
                    Interface.class.getClassLoader(),
                    new Class[]{Interface.class},
                    new DynamicProxyHandler(real));
            consumer(proxy);
        }
    }
    
    //输出:
    doSomething
    somethingElse jyu
    *** proxy:class com.sun.proxy.$Proxy0,
    method:public abstract void proxy.Interface.doSomething(),
    args:null
    doSomething
    *** proxy:class com.sun.proxy.$Proxy0,
    method:public abstract void proxy.Interface.somethingElse(java.lang.String),
    args:[Ljava.lang.Object;@355da254
        jyu
    somethingElse jyu
    
    

    PS:《java编程思想》中给咱们留的作业:使用动态代理来编写一个系统以实现事务,其中,代理在被代理的调用执行成功时(不抛出异常)执行提交,而在其执行失败时执行回滚。你的提交和回滚都针对一个外部的文本文件,该文件不在Java异常的控制控制范围之内。你必须注意操作的原子性

    3.Cglib代理

    cglib在android中是不能使用的,因此咱们这里先不讨论这项技术了。有兴趣的同学可以看看类似的文章。

    将cglib动态代理思想带入Android开发

    参考资料

    相关文章

      网友评论

          本文标题:Android中使用Java的动态代理

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