亚洲国产日韩欧美一区二区三区,精品亚洲国产成人av在线,国产99视频精品免视看7,99国产精品久久久久久久成人热,欧美日韩亚洲国产综合乱

Home Java JavaBase What is the difference between static proxy and dynamic proxy?

What is the difference between static proxy and dynamic proxy?

Dec 04, 2020 am 10:52 AM
dynamic proxy

Difference: The static proxy is created by the programmer or the tool generates the source code of the proxy class, and then compiles the proxy class; the bytecode file of the proxy class already exists before the program is run, and the relationship between the proxy class and the delegate class is determined before running. That’s it. The source code of the dynamic proxy class is dynamically generated by the JVM based on mechanisms such as reflection during program running, so there is no bytecode file for the proxy class.

What is the difference between static proxy and dynamic proxy?

Related recommendations: " Programming Video Course"

1. Agency Concept

Provide a proxy for an object to control access to the object. The proxy class and the delegate class have a common parent class or parent interface, so that the proxy object can be used wherever the delegate class object is used. The proxy class is responsible for request preprocessing, filtering, assigning requests to the delegate class for processing, and subsequent processing after the delegate class completes the request. Related recommendations: "Java Video Tutorial"

Figure 1: Proxy Mode

What is the difference between static proxy and dynamic proxy?

As can be seen from the figure, the proxy interface (Subject), proxy class (ProxySubject), and delegation class (RealSubject) form a "Pin" structure.
According to the generation time of the agent class, agents can be divided into two types: static agents and dynamic agents.

The following is a simulation requirement to illustrate static agents and dynamic agents: the delegate class needs to process a long-time task, and the client class needs to print out the time it takes to execute the task. To solve this problem, you need to record the time before task execution and the time after task execution. The difference between the two times is the time consumed by task execution.

2. Static proxy

Created by programmers or tools to generate the source code of the proxy class, and then compile the proxy class . The so-called static means that the bytecode file of the proxy class already exists before the program is run, and the relationship between the proxy class and the delegate class is determined before running.

Listing 1: Proxy interface

/**  
 * 代理接口。處理給定名字的任務。 
 */  
public interface Subject {  
  /** 
   * 執(zhí)行給定名字的任務。 
    * @param taskName 任務名 
   */  
   public void dealTask(String taskName);   
}

Listing 2: Delegate class , specifically handle business.

/** 
 * 真正執(zhí)行任務的類,實現(xiàn)了代理接口。 
 */  
public class RealSubject implements Subject {  
  
 /** 
  * 執(zhí)行給定名字的任務。這里打印出任務名,并休眠500ms模擬任務執(zhí)行了很長時間 
  * @param taskName  
  */  
   @Override  
   public void dealTask(String taskName) {  
      System.out.println("正在執(zhí)行任務:"+taskName);  
      try {  
         Thread.sleep(500);  
      } catch (InterruptedException e) {  
         e.printStackTrace();  
      }  
   }  
}

Listing 3: Static proxy class

/** 
 * 代理類,實現(xiàn)了代理接口。 
 */  
public class ProxySubject implements Subject {  
 //代理類持有一個委托類的對象引用  
 private Subject delegate;  
   
 public ProxySubject(Subject delegate) {  
  this.delegate = delegate;  
 }  
  
 /** 
  * 將請求分派給委托類執(zhí)行,記錄任務執(zhí)行前后的時間,時間差即為任務的處理時間 
  *  
  * @param taskName 
  */  
 @Override  
 public void dealTask(String taskName) {  
  long stime = System.currentTimeMillis();   
  //將請求分派給委托類處理  
  delegate.dealTask(taskName);  
  long ftime = System.currentTimeMillis();   
  System.out.println("執(zhí)行任務耗時"+(ftime - stime)+"毫秒");  
    
 }  
}

Listing 4: Generating static proxy class factory

public class SubjectStaticFactory {  
 //客戶類調(diào)用此工廠方法獲得代理對象。  
 //對客戶類來說,其并不知道返回的是代理類對象還是委托類對象。  
 public static Subject getInstance(){   
  return new ProxySubject(new RealSubject());  
 }  
}

清單5:客戶類

public class Client1 {  
  
 public static void main(String[] args) {  
  Subject proxy = SubjectStaticFactory.getInstance();  
  proxy.dealTask("DBQueryTask");  
 }   
  
}

靜態(tài)代理類優(yōu)缺點

優(yōu)點:業(yè)務類只需要關注業(yè)務邏輯本身,保證了業(yè)務類的重用性。這是代理的共有優(yōu)點。

缺點:

1)代理對象的一個接口只服務于一種類型的對象,如果要代理的方法很多,勢必要為每一種方法都進行代理,靜態(tài)代理在程序規(guī)模稍大時就無法勝任了。

2)如果接口增加一個方法,除了所有實現(xiàn)類需要實現(xiàn)這個方法外,所有代理類也需要實現(xiàn)此方法。增加了代碼維護的復雜度。

三、動態(tài)代理

動態(tài)代理類的源碼是在程序運行期間由JVM根據(jù)反射等機制動態(tài)的生成,所以不存在代理類的字節(jié)碼文件。代理類和委托類的關系是在程序運行時確定。

1、先看看與動態(tài)代理緊密關聯(lián)的Java API。

1)java.lang.reflect.Proxy

這是 Java 動態(tài)代理機制生成的所有動態(tài)代理類的父類,它提供了一組靜態(tài)方法來為一組接口動態(tài)地生成代理類及其對象。

清單6:Proxy類的靜態(tài)方法

// 方法 1: 該方法用于獲取指定代理對象所關聯(lián)的調(diào)用處理器  
static InvocationHandler getInvocationHandler(Object proxy)   
  
// 方法 2:該方法用于獲取關聯(lián)于指定類裝載器和一組接口的動態(tài)代理類的類對象  
static Class getProxyClass(ClassLoader loader, Class[] interfaces)   
  
// 方法 3:該方法用于判斷指定類對象是否是一個動態(tài)代理類  
static boolean isProxyClass(Class cl)   
  
// 方法 4:該方法用于為指定類裝載器、一組接口及調(diào)用處理器生成動態(tài)代理類實例  
static Object newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h)

2)java.lang.reflect.InvocationHandler

這是調(diào)用處理器接口,它自定義了一個 invoke 方法,用于集中處理在動態(tài)代理類對象上的方法調(diào)用,通常在該方法中實現(xiàn)對委托類的代理訪問。每次生成動態(tài)代理類對象時都要指定一個對應的調(diào)用處理器對象。

清單7:InvocationHandler的核心方法

// 該方法負責集中處理動態(tài)代理類上的所有方法調(diào)用。第一個參數(shù)既是代理類實例,第二個參數(shù)是被調(diào)用的方法對象  
// 第三個方法是調(diào)用參數(shù)。調(diào)用處理器根據(jù)這三個參數(shù)進行預處理或分派到委托類實例上反射執(zhí)行  
Object invoke(Object proxy, Method method, Object[] args)

3)java.lang.ClassLoader

這是類裝載器類,負責將類的字節(jié)碼裝載到 Java 虛擬機(JVM)中并為其定義類對象,然后該類才能被使用。Proxy 靜態(tài)方法生成動態(tài)代理類同樣需要通過類裝載器來進行裝載才能使用,它與普通類的唯一區(qū)別就是其字節(jié)碼是由 JVM 在運行時動態(tài)生成的而非預存在于任何一個 .class 文件中。

每次生成動態(tài)代理類對象時都需要指定一個類裝載器對象

2、動態(tài)代理實現(xiàn)步驟

具體步驟是:

a. 實現(xiàn)InvocationHandler接口創(chuàng)建自己的調(diào)用處理器

b. 給Proxy類提供ClassLoader和代理接口類型數(shù)組創(chuàng)建動態(tài)代理類

c. 以調(diào)用處理器類型為參數(shù),利用反射機制得到動態(tài)代理類的構造函數(shù)

d. 以調(diào)用處理器對象為參數(shù),利用動態(tài)代理類的構造函數(shù)創(chuàng)建動態(tài)代理類對象

清單8:分步驟實現(xiàn)動態(tài)代理

// InvocationHandlerImpl 實現(xiàn)了 InvocationHandler 接口,并能實現(xiàn)方法調(diào)用從代理類到委托類的分派轉發(fā)  
// 其內(nèi)部通常包含指向委托類實例的引用,用于真正執(zhí)行分派轉發(fā)過來的方法調(diào)用  
InvocationHandler handler = new InvocationHandlerImpl(..);   
  
// 通過 Proxy 為包括 Interface 接口在內(nèi)的一組接口動態(tài)創(chuàng)建代理類的類對象  
Class clazz = Proxy.getProxyClass(classLoader, new Class[] { Interface.class, ... });   
  
// 通過反射從生成的類對象獲得構造函數(shù)對象  
Constructor constructor = clazz.getConstructor(new Class[] { InvocationHandler.class });   
  
// 通過構造函數(shù)對象創(chuàng)建動態(tài)代理類實例  
Interface Proxy = (Interface)constructor.newInstance(new Object[] { handler });

Proxy類的靜態(tài)方法newProxyInstance對上面具體步驟的后三步做了封裝,簡化了動態(tài)代理對象的獲取過程。
清單9:簡化后的動態(tài)代理實現(xiàn)

// InvocationHandlerImpl 實現(xiàn)了 InvocationHandler 接口,并能實現(xiàn)方法調(diào)用從代理類到委托類的分派轉發(fā)  
InvocationHandler handler = new InvocationHandlerImpl(..);   
  
// 通過 Proxy 直接創(chuàng)建動態(tài)代理類實例  
Interface proxy = (Interface)Proxy.newProxyInstance( classLoader,   
     new Class[] { Interface.class },  handler );

3、動態(tài)代理實現(xiàn)示例

清單10:創(chuàng)建自己的調(diào)用處理器

/** 
 * 動態(tài)代理類對應的調(diào)用處理程序類 
 */  
public class SubjectInvocationHandler implements InvocationHandler {  
   
 //代理類持有一個委托類的對象引用  
 private Object delegate;  
   
 public SubjectInvocationHandler(Object delegate) {  
  this.delegate = delegate;  
 }  
   
 @Override  
 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {  
  long stime = System.currentTimeMillis();   
  //利用反射機制將請求分派給委托類處理。Method的invoke返回Object對象作為方法執(zhí)行結果。  
  //因為示例程序沒有返回值,所以這里忽略了返回值處理  
  method.invoke(delegate, args);  
  long ftime = System.currentTimeMillis();   
  System.out.println("執(zhí)行任務耗時"+(ftime - stime)+"毫秒");  
    
  return null;  
 }  
}

清單11:生成動態(tài)代理對象的工廠,工廠方法列出了如何生成動態(tài)代理類對象的步驟。

/** 
 * 生成動態(tài)代理對象的工廠. 
 */  
public class DynProxyFactory {  
 //客戶類調(diào)用此工廠方法獲得代理對象。  
 //對客戶類來說,其并不知道返回的是代理類對象還是委托類對象。  
 public static Subject getInstance(){   
  Subject delegate = new RealSubject();  
  InvocationHandler handler = new SubjectInvocationHandler(delegate);  
  Subject proxy = null;  
  proxy = (Subject)Proxy.newProxyInstance(  
    delegate.getClass().getClassLoader(),   
    delegate.getClass().getInterfaces(),   
    handler);  
  return proxy;  
 }  
}

清單12:動態(tài)代理客戶類

public class Client {  
  
 public static void main(String[] args) {  
  
  Subject proxy = DynProxyFactory.getInstance();  
  proxy.dealTask("DBQueryTask");  
 }   
  
}

4、動態(tài)代理機制特點??

首先是動態(tài)生成的代理類本身的一些特點。1)包:如果所代理的接口都是 public 的,那么它將被定義在頂層包(即包路徑為空),如果所代理的接口中有非 public 的接口(因為接口不能被定義為 protect 或 private,所以除 public 之外就是默認的 package 訪問級別),那么它將被定義在該接口所在包(假設代理了 com.ibm.developerworks 包中的某非 public 接口 A,那么新生成的代理類所在的包就是 com.ibm.developerworks),這樣設計的目的是為了最大程度的保證動態(tài)代理類不會因為包管理的問題而無法被成功定義并訪問;2)類修飾符:該代理類具有 final 和 public 修飾符,意味著它可以被所有的類訪問,但是不能被再度繼承;3)類名:格式是“$ProxyN”,其中 N 是一個逐一遞增的阿拉伯數(shù)字,代表 Proxy 類第 N 次生成的動態(tài)代理類,值得注意的一點是,并不是每次調(diào)用 Proxy 的靜態(tài)方法創(chuàng)建動態(tài)代理類都會使得 N 值增加,原因是如果對同一組接口(包括接口排列的順序相同)試圖重復創(chuàng)建動態(tài)代理類,它會很聰明地返回先前已經(jīng)創(chuàng)建好的代理類的類對象,而不會再嘗試去創(chuàng)建一個全新的代理類,這樣可以節(jié)省不必要的代碼重復生成,提高了代理類的創(chuàng)建效率。4)類繼承關系:該類的繼承關系如圖:?

圖2:動態(tài)代理類的繼承關系?

What is the difference between static proxy and dynamic proxy?

As can be seen from the figure, the Proxy class is its parent class. This rule applies to all dynamic proxy classes created by Proxy. And this class also implements a set of interfaces it proxies, which is the fundamental reason why it can be safely type-cast to an interface it proxies.

Next let’s take a look at some characteristics of proxy class instances. Each instance is associated with an invocation handler object. You can obtain the invocation handler object of the proxy class instance through the static method getInvocationHandler provided by Proxy. When the methods declared in the interface of its proxy are called on the proxy class instance, these methods will eventually be executed by the invoke method of the calling processor. In addition, it is worth noting that there are three in the root class java.lang.Object of the proxy class. The methods will also be dispatched to the invoke method of the calling processor for execution, they are hashCode, equals and toString. The possible reasons are: first, because these methods are public and non-final types and can be overridden by the proxy class; second, because these methods Methods often present certain characteristic attributes of a class and have a certain degree of distinction. Therefore, in order to ensure the external consistency of the proxy class and the delegate class, these three methods should also be assigned to the delegate class for execution. When a set of interfaces of a proxy has a repeatedly declared method and the method is called, the proxy class always obtains the method object from the frontmost interface and dispatches it to the calling handler, regardless of whether the proxy class instance is using that interface. (or a sub-interface inherited from this interface) is externally referenced because its current referenced type cannot be distinguished within the proxy class.

Then let’s take a look at the characteristics of a group of interfaces being proxied. First of all, be careful not to have duplicate interfaces to avoid compilation errors when generating dynamic proxy class code. Secondly, these interfaces must be visible to the class loader, otherwise the class loader will not be able to link them, causing the class definition to fail. Thirdly, all non-public interfaces that need to be proxied must be in the same package, otherwise the proxy class generation will also fail. Finally, the number of interfaces cannot exceed 65535, which is a limit set by the JVM.

Finally, let’s take a look at the characteristics of exception handling. From the method declared by the calling processor interface, we can see that in theory it can throw any type of exception, because all exceptions inherit from the Throwable interface, but is this the case? The answer is no, because we must abide by an inheritance principle: that is, when a subclass overrides a method of a parent class or implements a parent interface, the exception thrown must be within the exception list supported by the original method. So although calling the handler is theoretically possible, in practice it is often restricted unless the method in the parent interface supports throwing Throwable exceptions. So what happens if an exception that is not supported in the interface method declaration does occur in the invoke method? Don't worry, the Java dynamic proxy class has already designed a solution for us: it will throw an UndeclaredThrowableException exception. This exception is a RuntimeException type, so it will not cause compilation errors. Through the exception's getCause method, you can also obtain the original unsupported exception object to facilitate error diagnosis.

5. Advantages and disadvantages of dynamic proxy

Advantages:

Compared with static proxies, the biggest advantage of dynamic proxies is that all methods declared in the interface are transferred to a centralized method of the invocation processor (InvocationHandler.invoke). In this way, when there are a large number of interface methods, we can flexibly handle them without having to transfer each method like a static proxy. It cannot be seen in this example because specific peripheral services are embedded in the invoke method body (recording the time before and after task processing and calculating the time difference). In practice, peripheral services can be configured similar to Spring AOP.

Flaws in the ointment:

It is true that Proxy has been designed very beautifully, but there is still a little regret, that is It has never been able to get rid of the shackles of only supporting interface proxy, because its design is doomed to this regret. Recall the inheritance diagram of those dynamically generated proxy classes. They are destined to have a common parent class called Proxy. Java's inheritance mechanism is destined that these dynamic proxy classes cannot implement dynamic proxy for classes. The reason is that multiple inheritance essentially does not work in Java.

There are many reasons why people can deny the necessity of class proxies, but there are also some reasons to believe that supporting class dynamic proxies would be better. The division between interfaces and classes is not very obvious to begin with. It is only in Java that it becomes so detailed. If we only consider the method declaration and whether it is defined, there is a mixture of the two, and its name is abstract class. I believe that implementing dynamic proxy for abstract classes also has its inherent value. In addition, there are some classes left over from history, which will never be associated with dynamic agents because they do not implement any interfaces. With all this going on, it has to be said that it is a small regret. ?????????????

If you want to read more related articles, please visit PHP Chinese website! !

The above is the detailed content of What is the difference between static proxy and dynamic proxy?. For more information, please follow other related articles on the PHP Chinese website!

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undress AI Tool

Undress AI Tool

Undress images for free

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

Hot Topics

PHP Tutorial
1488
72
Reflection mechanism implementation of interfaces and abstract classes in Java Reflection mechanism implementation of interfaces and abstract classes in Java May 02, 2024 pm 05:18 PM

The reflection mechanism allows programs to obtain and modify class information at runtime. It can be used to implement reflection of interfaces and abstract classes: Interface reflection: obtain the interface reflection object through Class.forName() and access its metadata (name, method and field) . Reflection of abstract classes: Similar to interfaces, you can obtain the reflection object of an abstract class and access its metadata and non-abstract methods. Practical case: The reflection mechanism can be used to implement dynamic proxies, intercepting calls to interface methods at runtime by dynamically creating proxy classes.

Application of Java reflection mechanism in Spring framework? Application of Java reflection mechanism in Spring framework? Apr 15, 2024 pm 02:03 PM

Java reflection mechanism is widely used in Spring framework for the following aspects: Dependency injection: instantiating beans and injecting dependencies through reflection. Type conversion: Convert request parameters to method parameter types. Persistence framework integration: mapping entity classes and database tables. AspectJ support: intercepting method calls and enhancing code behavior. Dynamic Proxy: Create proxy objects to enhance the behavior of the original object.

How to implement dynamic proxy in Java anonymous inner class? How to implement dynamic proxy in Java anonymous inner class? Apr 30, 2024 pm 05:36 PM

In Java, you can use anonymous inner classes to implement dynamic proxy by following the following steps: 1. Define the interface; 2. Create an anonymous inner class that implements the InvocationHandler interface; 3. Use the Proxy class to create a proxy object; 4. Call the proxy method. In practice, dynamic proxies can enhance or intercept method calls, such as recording method execution time.

How is the Java reflection mechanism used in testing and debugging? How is the Java reflection mechanism used in testing and debugging? May 01, 2024 pm 06:48 PM

In testing and debugging, Java reflection mechanism can be used to: test private fields and methods, access invisible information. Create dynamic proxies, intercept behavior and simulate it. Validate coding conventions to ensure best practices and maintainability. Check object status, diagnose errors and behavior. Change object status for quick experimentation and troubleshooting.

How to use reflection to implement dynamic proxy mode in golang How to use reflection to implement dynamic proxy mode in golang May 01, 2024 pm 09:57 PM

Using Reflection to Implement Dynamic Proxy in Go Answer: Yes, the dynamic proxy pattern can be implemented in Go through reflection. Steps: Create a custom proxy type that contains target object reference and method processing logic. Create proxy methods for proxy types that perform additional logic before or after calling the target method. Use reflection to dynamically call the target method, using the reflect.Value type and the Call method.

In-depth analysis of reflection and dynamic proxy technology in Java development In-depth analysis of reflection and dynamic proxy technology in Java development Nov 20, 2023 am 10:00 AM

In-depth analysis of reflection and dynamic proxy technology in Java development Introduction: In Java development, reflection and dynamic proxy technology are two very important concepts. They provide developers with a flexible way to manipulate classes and objects, allowing programs to dynamically obtain and call class information at runtime. This article will provide an in-depth analysis of reflection and dynamic proxy technology in Java development, and analyze its application scenarios and advantages in actual development. 1. The definition and principle of reflection technology. The concept of reflection. Reflection is a kind of function provided by the Java programming language that can be run at runtime.

How to implement dynamic proxy using reflection function in Java How to implement dynamic proxy using reflection function in Java Oct 18, 2023 am 08:48 AM

How to use reflection functions to implement dynamic agents in Java Introduction: The reflection mechanism in Java allows us to dynamically obtain and operate class information at runtime, including class methods, fields, constructors, etc. Dynamic proxy refers to creating a proxy class object that implements a certain interface at runtime. Method calls of the proxy class will be forwarded to the implementation class of the InvocationHandler interface. This article will introduce how to use Java's reflection mechanism to implement dynamic proxy, helping readers better understand and apply this technology. dynamic

How to connect interfaces in java How to connect interfaces in java Apr 21, 2024 am 02:08 AM

The steps for Java docking interface: 1. Define the interface; 2. Implement the interface; 3. Create a proxy class; 4. Get the proxy instance; 5. Call the interface method.

See all articles