Code separation and decoupling of mobile architecture - network re-isolation

640?wx_fmt=gif&wxfrom=5&wx_lazy=1

Hot Article Guide |  Click on the title to read

How to advance to become an Android architect?

so cool! 74 APP complete source code!

Welcome to Java and Android Architecture Knowledge Planet

The concept of agency

Provides a proxy for an object to control access to this object. The proxy class and the delegate class have a common parent class or parent interface, so that wherever the delegate class object is used, the proxy object can be used instead. The proxy class is responsible for request preprocessing, filtering, dispatching the request to the delegate class for processing, and subsequent processing after the delegate class executes the request .

Figure 1: Proxy Pattern

640?wx_fmt=png&wxfrom=5&wx_lazy=1


As can be seen from the figure, the proxy interface (Subject), the proxy class (ProxySubject), and the delegate class (RealSubject) form a "product" structure.

According to the generation time of the proxy class, the proxy can be divided into static proxy and dynamic proxy.

The following describes static proxy and dynamic proxy with a simulated requirement: the delegate class needs to process a long-time task, and the client class needs to print out the time consumed by executing the task. To solve this problem, it is necessary to record the time before the task is executed and the time after the task is executed. The difference between the two times is the time consumed by the task execution.

2. Static proxy

The source code of the proxy class is generated by our own creation or tool, and then the proxy class is compiled. The so-called static means that the bytecode file of the proxy class already exists before the program runs, and the relationship between the proxy class and the delegate class is determined before running.

1: Proxy interface

 

640?wx_fmt=png


Listing 3: Static proxy class

640?wx_fmt=png

640?wx_fmt=png


Advantages and disadvantages of static proxy classes

Advantages: The business class only needs to focus on the business logic itself, which ensures the reusability of the business class. This is a common advantage of proxies.
Disadvantages:
1) An interface of the proxy object only serves one type of object. If there are many methods to be proxyed, it is necessary to proxy for each method. Static proxy cannot be competent when the program scale is slightly larger.
2) If a method is added to the interface, in addition to all implementing classes need to implement this method, all proxy classes also need to implement this method. Increases the complexity of code maintenance.

3. Dynamic Agent

The source code of the dynamic proxy class is dynamically generated by the JVM according to mechanisms such as reflection during the running of the program, so there is no bytecode file of the proxy class. The relationship between the proxy class and the delegate class is determined when the program is running.

1. Let's first look at the Java API that is closely associated with dynamic proxies.
1) java.lang.reflect.Proxy
This is the parent class of all dynamic proxy classes generated by the Java dynamic proxy mechanism. It provides a set of static methods to dynamically generate proxy classes and their objects for a set of interfaces.


Static method of Proxy class

640?wx_fmt=png

java.lang.reflect.InvocationHandler

This is the call handler interface, which defines an invoke method to centrally process method calls on the dynamic proxy class object, and usually implements proxy access to the delegate class in this method. Each time a dynamic proxy class object is generated, a corresponding call handler object must be specified.

Listing 7: Core methods of InvocationHandler

640?wx_fmt=png

java.lang.ClassLoader

The specific steps are:

a. Implement the InvocationHandler interface to create your own invocation handler
b. Provide a ClassLoader and an array of proxy interface types to the Proxy class to create a dynamic proxy class
c. Take the invocation handler type as a parameter and use the reflection mechanism to get the constructor of the dynamic proxy class
d. Take Call the processor object as a parameter, and use the constructor of the dynamic proxy class to create a dynamic proxy class object

Listing 8: Implementing a dynamic proxy in steps

640?wx_fmt=png


The static method newProxyInstance of the Proxy class encapsulates the last three steps of the above specific steps, which simplifies the process of obtaining dynamic proxy objects.

Listing 9: Example of dynamic proxy implementation

640?wx_fmt=png


Characteristics of dynamic proxy mechanism

The first is some characteristics of the dynamically generated proxy class itself.

1)包:如果所代理的接口都是 public 的,那么它将被定义在顶层包(即包路径为空),如果所代理的接口中有非 public 的接口(因为接口不能被定义为 protect 或 private,所以除 public 之外就是默认的 package 访问级别),那么它将被定义在该接口所在包(假设代理了 com.ibm.developerworks 包中的某非 public 接口 A,那么新生成的代理类所在的包就是 com.ibm.developerworks),这样设计的目的是为了最大程度的保证动态代理类不会因为包管理的问题而无法被成功定义并访问;

2)类修饰符:该代理类具有 final 和 public 修饰符,意味着它可以被所有的类访问,但是不能被再度继承;

3)类名:格式是“$ProxyN”,其中 N 是一个逐一递增的阿拉伯数字,代表 Proxy 类第 N 次生成的动态代理类,值得注意的一点是,并不是每次调用 Proxy 的静态方法创建动态代理类都会使得 N 值增加,原因是如果对同一组接口(包括接口排列的顺序相同)试图重复创建动态代理类,它会很聪明地返回先前已经创建好的代理类的类对象,而不会再尝试去创建一个全新的代理类,这样可以节省不必要的代码重复生成,提高了代理类的创建效率。

4)类继承关系:该类的继承关系如图:

640?wx_fmt=png


由图可见,Proxy 类是它的父类,这个规则适用于所有由 Proxy 创建的动态代理类。而且该类还实现了其所代理的一组接口,这就是为什么它能够被安全地类型转换到其所代理的某接口的根本原因。

接下来让我们了解一下代理类实例的一些特点。每个实例都会关联一个调用处理器对象,可以通过 Proxy 提供的静态方法 getInvocationHandler 去获得代理类实例的调用处理器对象。在代理类实例上调用其代理的接口中所声明的方法时,这些方法最终都会由调用处理器的 invoke 方法执行,此外,值得注意的是,代理类的根类 java.lang.Object 中有三个方法也同样会被分派到调用处理器的 invoke 方法执行,它们是 hashCode,equals 和 toString,可能的原因有:一是因为这些方法为 public 且非 final 类型,能够被代理类覆盖;二是因为这些方法往往呈现出一个类的某种特征属性,具有一定的区分度,所以为了保证代理类与委托类对外的一致性,这三个方法也应该被分派到委托类执行。当代理的一组接口有重复声明的方法且该方法被调用时,代理类总是从排在最前面的接口中获取方法对象并分派给调用处理器,而无论代理类实例是否正在以该接口(或继承于该接口的某子接口)的形式被外部引用,因为在代理类内部无法区分其当前的被引用类型。

接着来了解一下被代理的一组接口有哪些特点。首先,要注意不能有重复的接口,以避免动态代理类代码生成时的编译错误。其次,这些接口对于类装载器必须可见,否则类装载器将无法链接它们,将会导致类定义失败。再次,需被代理的所有非 public 的接口必须在同一个包中,否则代理类生成也会失败。最后,接口的数目不能超过 65535,这是 JVM 设定的限制。

最后再来了解一下异常处理方面的特点。从调用处理器接口声明的方法中可以看到理论上它能够抛出任何类型的异常,因为所有的异常都继承于 Throwable 接口,但事实是否如此呢?答案是否定的,原因是我们必须遵守一个继承原则:即子类覆盖父类或实现父接口的方法时,抛出的异常必须在原方法支持的异常列表之内。所以虽然调用处理器理论上讲能够,但实际上往往受限制,除非父接口中的方法支持抛 Throwable 异常。那么如果在 invoke 方法中的确产生了接口方法声明中不支持的异常,那将如何呢?放心,Java 动态代理类已经为我们设计好了解决方法:它将会抛出 UndeclaredThrowableException 异常。这个异常是一个 RuntimeException 类型,所以不会引起编译错误。通过该异常的 getCause 方法,还可以获得原来那个不受支持的异常对象,以便于错误诊断。

5、动态代理的优点和美中不足

优点:

动态代理与静态代理相比较,最大的好处是接口中声明的所有方法都被转移到调用处理器一个集中的方法中处理(InvocationHandler.invoke)。这样,在接口方法数量比较多的时候,我们可以进行灵活处理,而不需要像静态代理那样每一个方法进行中转。在本示例中看不出来,因为invoke方法体内嵌入了具体的外围业务(记录任务处理前后时间并计算时间差),实际中可以类似

美中不足:

诚然,Proxy 已经设计得非常优美,但是还是有一点点小小的遗憾之处,那就是它始终无法摆脱仅支持 interface 代理的桎梏,因为它的设计注定了这个遗憾。回想一下那些动态生成的代理类的继承关系图,它们已经注定有一个共同的父类叫 Proxy。Java 的继承机制注定了这些动态代理类们无法实现对 class 的动态代理,原因是多继承在 Java 中本质上就行不通。

There are many reasons why one could deny the need for class proxies, but there are also reasons to believe that it would be better to support class dynamic proxies. The division of interfaces and classes is not very obvious, but it has become so refined in Java. If you only consider the declaration of the method and whether it is defined, there is a hybrid of the two, and its name is an abstract class. It is believed that there is inherent value in implementing dynamic proxy for abstract classes. In addition, there are some legacy classes that will never live with dynamic proxies because they don't implement any interfaces. It's a small regret that I have to say.

Author: Android Department of Brain College
Link: https://www.jianshu.com/p/2c36fa519cec

If you have a good article that you want to share with you, you are welcome to contribute, just send me the article link directly


Finally, everyone is welcome to join our knowledge planet. The second phase is in full swing, and nearly 1,000 people have joined the study :

Everyone is welcome to join as soon as possible. This period ends on March 10, 2019, so the sooner you join, the better. The promotion ends. The current entry fee has been raised from 79 yuan to 89 yuan, and the fee will increase by 10 yuan for every 100 people in the future~

640?wx_fmt=jpeg

Scan WeChat or click the QR code above to get Android\Python\AI\Java and other advanced resources

For more learning materials, click "Read the original text " below

640?wx_fmt=gif

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325342310&siteId=291194637