The origin of this blog , Before we learned big talk design , You'll understand the proxy model , But why ?

reason :

1, adopt DRP This project , Learn about dynamic proxies , Realize that we've been using static proxies , So what are the benefits of dynamic proxy ? What is the difference between them ?

2, Through learning dynamic agent, we can know that dynamic agent is a kind of compliance AOP Technology of design idea , So what is it AOP?

Here is my understanding of them !


agent Proxy:


Proxy Agent pattern is a structural design pattern , The main problem to be solved is : Problems with direct access to objects


Proxy is a common design pattern , Its purpose is to provide a proxy for other objects to control access to an object . The proxy class is responsible for preprocessing messages for the delegate class , Forward the message and filter the message , And the subsequent processing after the message is executed by the delegate class .


In order to maintain the consistency of behavior , Proxy and delegate classes usually implement the same interface , So in the eyes of visitors, there is no difference between the two . Through the middle layer of proxy class , It can effectively control the direct access to delegate class objects , It can also well hide and protect delegate class objects , At the same time, space is reserved for the implementation of different control strategies , Thus, more flexibility is obtained in the design .


More generally , The proxy solves the problem when two classes need to communicate , Introduce the third party proxy class , Decouple the relationship between the two classes , Let's just look at the proxy class , Moreover, the emergence of proxy can also let us complete the unified management of the relationship with another class , But remember , The proxy class and the delegate class should implement the same interface , Because the proxy really calls the method of the delegate class .


Examples of usage :

If you need to delegate a class to handle a business , Then we can first unify the processing in the proxy class, and then call the specific implementation class


According to the creation period of the agent , There are two types of proxy classes : 

static state : The programmer creates a proxy class or a specific tool, automatically generates the source code, and then compiles it . Of the proxy class before the program runs .class The file already exists .

dynamic : It is created dynamically by using reflection mechanism when the program is running .


Here is an example of a static proxy and a dynamic proxy :

Add the function of printing log , That is, before and after each method call, the log is written


Static proxy :


Specific user management implementation class

public class UserManagerImpl implements UserManager { @Override public void
addUser(String userId, String userName) {
System.out.println("UserManagerImpl.addUser"); } @Override public void
delUser(String userId) { System.out.println("UserManagerImpl.delUser"); }
@Override public String findUser(String userId) {
System.out.println("UserManagerImpl.findUser"); return " Zhang San "; } @Override public
void modifyUser(String userId, String userName) {
System.out.println("UserManagerImpl.modifyUser"); } }

proxy class -- Proxy user management implementation class

public class UserManagerImplProxy implements UserManager { // Target object private
UserManager userManager; // Pass in the target object through the constructor public
UserManagerImplProxy(UserManager userManager){ this.userManager=userManager; }
@Override public void addUser(String userId, String userName) { try{
// Add the function of printing log // Start adding users System.out.println("start-->addUser()");
userManager.addUser(userId, userName); // User added successfully
System.out.println("success-->addUser()"); }catch(Exception e){ // Failed to add user
System.out.println("error-->addUser()"); } } @Override public void
delUser(String userId) { userManager.delUser(userId); } @Override public String
findUser(String userId) { userManager.findUser(userId); return " Zhang San "; }
@Override public void modifyUser(String userId, String userName) {
userManager.modifyUser(userId,userName); } }

Client call

public class Client { public static void main(String[] args){ //UserManager
userManager=new UserManagerImpl(); UserManager userManager=new
UserManagerImplProxy(new UserManagerImpl()); userManager.addUser("1111", " Zhang San ");
} }

Advantages and disadvantages of static proxy class


advantage :


The proxy keeps the client from knowing what the implementation class is , How to do it , The client only needs to know the agent ( Decoupling ), For the client code above ,newUserManagerImpl() You can hide it with the factory , The above is just an example .


shortcoming :

) The proxy class and the delegate class implement the same interface , The proxy class implements the same method through the delegate class . So there's a lot of code duplication . If the interface adds a method , Except that all implementation classes need to implement this method , All proxy classes also need to implement this method . It increases the complexity of code maintenance .

2) Proxy objects serve only one type of object , If you want to serve multiple types of objects . There must be proxy for every object , Static proxies don't work when the program is a little larger . The code above is only for
UserManager Class provides proxy access , But for other classes like Department Class provides a proxy , We need to add agents again Department Proxy class for .


Examples : Agents can manage implementation classes uniformly , For example, before calling the concrete implementation class , Need to print log and other information , In this way, we only need to add a proxy class , Add the function of printing log in agent class , And then call the implementation class. , This avoids modifying the concrete implementation class . Meet the principle of opening and closing . But if you want each implementation class to add the function of printing log , You need to add multiple proxy classes , And each method in the proxy class needs to add the function of printing log ( Delete from the above proxy method , modify , As well as query, you need to add the function of printing log )

That is, static proxy classes can only be specific interfaces (Service) service . If you want to serve multiple interfaces, you need to create many proxy classes .

Introducing dynamic proxy :


According to the above introduction , You will find that each proxy class can only serve one interface , In this way, a lot of proxy classes will be produced in the program development

So we will find a way to complete all the proxy functions through a proxy class , So we need to use dynamic proxy


In the example above , A proxy can only proxy one type , Moreover, the compiler has already determined the proxy object . And the dynamic agent is at runtime , Implementing dynamic proxy through reflection mechanism , And can proxy various types of objects


stay Java In order to achieve dynamic proxy mechanism , need java.lang.reflect.InvocationHandler Interface and
java.lang.reflect.Proxy Class support


java.lang.reflect.InvocationHandler The interface is defined as follows :

//Object proxy: Represented object //Method method: Method to call //Object[] args: Parameter required when method is called public
interface InvocationHandler { public Object invoke(Object proxy, Method method,
Object[] args) throws Throwable; }

java.lang.reflect.Proxy Class is defined as follows :

//CLassLoader loader: Class loader //Class<?> interfaces: Get all the interfaces //InvocationHandler
h: obtain InvocationHandler An instance of a subclass of an interface public static Object newProxyInstance(ClassLoader
loader, Class<?>[] interfaces, InvocationHandler h) throws

Dynamic proxy :


Concrete implementation class

public class UserManagerImpl implements UserManager { @Override public void
addUser(String userId, String userName) {
System.out.println("UserManagerImpl.addUser"); } @Override public void
delUser(String userId) { System.out.println("UserManagerImpl.delUser"); }
@Override public String findUser(String userId) {
System.out.println("UserManagerImpl.findUser"); return " Zhang San "; } @Override public
void modifyUser(String userId, String userName) {
System.out.println("UserManagerImpl.modifyUser"); } }

Dynamically create classes for proxy objects

// Dynamic proxy classes can only proxy interfaces ( Abstract classes are not supported ), Proxy classes need to be implemented InvocationHandler class , realization invoke method . The invoke Method is called when all methods of the proxy interface are called , The invoke The value returned by the method is an implementation class of the proxy interface
public class LogHandler implements InvocationHandler { // Target object private Object
targetObject; // Binding relationship , Which interface is associated with ( Binding with specific implementation classes ) When which methods of will be called , implement invoke method . public Object
newProxyInstance(Object targetObject){ this.targetObject=targetObject;
// This method is used to specify the class loader , A group of interfaces and call processors to generate dynamic proxy class instances // The first parameter specifies the class loader that generates the proxy object , It needs to be specified as the same class loader as the target object
// The second parameter implements the same interface as the target object , So you just need to get the implementation interface of the target object
// The third parameter indicates which intercepted method needs to be executed when intercepted InvocationHandler Of invoke method // Returns a proxy object based on the target passed in return
targetObject.getClass().getInterfaces(),this); } @Override
// When the method of the associated implementation class is called, it will be executed
/*InvocationHandler Interface method ,proxy Represents a proxy ,method Represents the method that the original object was called ,args Represents the parameter of the method */ public
Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("start-->>"); for(int i=0;i<args.length;i++){
System.out.println(args[i]); } Object ret=null; try{ /* Processing log information before calling original object method */
System.out.println("satrt-->>"); // Call target method ret=method.invoke(targetObject,
args); /* Post processing log information of original object method call */ System.out.println("success-->>"); }catch(Exception
e){ e.printStackTrace(); System.out.println("error-->>"); throw e; } return
ret; } }

Surrogate object targetObject It's passed in through parameters , We passed targetObject.getClass().getClassLoader() obtain ClassLoader object , And then through the targetObject.getClass().getInterfaces() Gets all the interfaces it implements , Then the targetObject Packaging to achieve InvocationHandler Interface LogHandler Object . adopt newProxyInstance Function, we get a dynamic proxy object .


Client code
public class Client { public static void main(String[] args){ LogHandler
logHandler=new LogHandler(); UserManager
userManager=(UserManager)logHandler.newProxyInstance(new UserManagerImpl());
//UserManager userManager=new UserManagerImpl(); userManager.addUser("1111",
" Zhang San "); } }

You can see , We can go through LogHandler Proxy different types of objects , If we implement all external interfaces through dynamic proxy , Then all function calls will eventually go through invoke Function forwarding , So we can do what we want to do here , For example, the log system , affair , Interceptor , Authority control, etc . That's what it is AOP( Aspect oriented programming ) The basic principle of .


episode :

AOP(AspectOrientedProgramming): Log , Performance statistics , safety control , transaction processing , Exception handling code is divided from business logic code , Through the separation of these behaviors , We want to be able to separate them from the non directive business logic approach , And then change these behaviors without affecting the business logic code
--- decoupling .


For the above example explanation :


Let's take a look at the top UserManagerImplProxy class , It's two ways System.out.println("start-->addUser()") and System.out.println("success-->addUser()"), These are the two interceptions before and after the core action , These are the two interceptions , It's us AOP The foundation of , stay OOP in ,System.out.println("start-->addUser()"), Core action ,System.out.println("success-->addUser()") These three actions are always together in multiple classes , But their logic is different , as System.out.println("start-->addUser()") It may be the judgment of authority , In all classes, it does permission judgment , In each class, the core actions are different ,System.out.println("success-->addUser()") What might be done is a log , It logs in all classes . It's because in all classes , The operation before the core code and the operation after the core code do the same logic , So we need to extract them , Separate analysis , Design and coding , This is what we have AOP thought . In a word ,
AOP It's just right OOP On the basis of further abstraction , Make our class's responsibilities more single .

Advantages of dynamic proxy :


Comparing dynamic agent with static agent , The biggest benefit is that all methods declared in the interface are transferred to a centralized method of the call processor (InvocationHandler.invoke). such , When there are many interface methods , We can be flexible , There is no need to transit every method like static proxy . Moreover, the application of dynamic proxy makes our class responsibility more single , More reusable


summary :


In fact, the so-called agency , It's a person or an organization acting on behalf of another person or another organization . In some cases , A customer does not want or can't directly refer to an object , The proxy object can act as a mediator before the client and the target object .


The proxy object is to wrap the proxy object in one layer , Do some extra work inside , For example, users need to facebook, But ordinary network can not be directly accessed , Network agent helps users to cross the wall first , Then visit facebook. That's what agents do .

Static agent and dynamic agent , They all do the same thing , Let's look at the process from static proxy to dynamic proxy , We will find that the dynamic proxy only abstracts and encapsulates the class , The reusability and ease of use are further improved, which is not only in line with the object-oriented design concept , There are also
AOP The figure of , This also provides us with a reference to class abstraction . On dynamic proxy and AOP The relationship between , I feel that AOP It's an idea , And dynamic proxy is a kind of AOP Realization of ideas !

©2019-2020 Toolsou All rights reserved,
Error summary -myBatis plus paging use easyPOI Import Excel data In the problem of target detection “ recall Recall”,“ Accuracy Precision”vue use vue-clipboard2 Realize the function of copy link C In language switch sentence Wechat applet (uni-app)url Parameter transfer object hive compress &&hdfs Merge small files hive Summary of processing methods for a large number of small files use spring Of AntPathMatcher matching url route Linux Page replacement algorithm C Language implementation