Reproduced in this article + personal understanding
First, Introduction
When we learn spring, we know that spring has two main ideas, one is the IOC, the other is AOP, and for IOC, dependency injection doesn't have to say much, and for spring's core AOP, Not only do we need to know how to satisfy our function through AOP, what we need to learn is how the underlying is a principle, and the principle of AOP is the dynamic agent mechanism of Java , so this essay is a review of the dynamic mechanism of java.
Ii. Overview
In the dynamic agent mechanism of Java, there are two important classes or interfaces, one is invocationhandler(Interface), the other is proxy(Class), This class and interface is required to implement our dynamic proxies. First, let's take a look at how the Java API Help document describes these two classes:
Invocationhandler:
Invocationhandler is the interface implemented by the invocation handler of a proxy instance. Each proxy instance have an associated invocation handler. When a method was invoked on a proxy instance
The method invocation is encoded and dispatched to the Invoke method of its invocation handler.
each dynamic proxy class must implement the Invocationhandler interface, and each instance of the proxy class is associated with a handler, and when we call a method through the proxy object, The invocation of this method is forwarded to the Invoke method of this interface by Invocationhandler . Let's take a look at the only way to invocationhandler this interface. The Invoke method:
Throws Throwable
We see that this method takes three parameters altogether, so what do these three parameters represent?
Throws throwableproxy: refers to the real object method we represent : Refers to the method object that we are going to call the real object. args: refers to the arguments that are accepted when a method of a real object is called
If not very clear, wait for an example to explain these parameters in more depth.
Next we look at the proxy class:
The role of the proxy class is to dynamically create a class of proxy objects, which provides a number of methods, but the most we use is newproxyinstance this method:
Newproxyinstance (ClassLoader loader, class<?>[] interfaces,
Throws IllegalArgumentException
To the specified invocation handler.
The function of this method is to get a dynamic proxy object, which receives three parameters, and we take a look at what these three parameters mean:
Throws illegalargumentexceptionloader: A ClassLoader object that defines which ClassLoader object to load on the generated proxy object Interfaces: An array of interface objects, which means I'm going to give the object that I need the proxy to provide a set of what interfaces, if I provide a set of interfaces to it,
The proxy object then declares that the interface (polymorphic) is implemented so that I can invoke the methods in this set of interfaces.
This is the dynamic agent of a core, through the parameter transfer, the implementation of related interfaces.
h: A Invocationhandler object that represents the Invocationhandler object to which the dynamic proxy object is associated when it invokes the method.
Third, examples
First we define an interface of type subject and declare two methods for it:
1 Public Interface Subject 2 {3 Public void rent (); 4 5 Public void Hello (String str); 6 }
Next, define a class to implement this interface, this class is our real object, Realsubject class:
1 Public classRealsubjectImplementsSubject2 {3 @Override4 Public voidrent ()5 {6System.out.println ("I want to rent my house");7 }8 9 @OverrideTen Public voidHello (String str) One { ASystem.out.println ("Hello:" +str); - } -}
Next, we are going to define a dynamic proxy class, the previous one, each dynamic proxy class must implement Invocationhandler this interface , so we this dynamic proxy class is no exception:
1 Public classDynamicproxyImplementsInvocationhandler2 {3 //This is the real object we're going to be acting for.4 PrivateObject subject;5 6 //constructs a method, assigns the initial value to the real object which we want to proxy7 PublicDynamicproxy (Object subject)8 {9 This. Subject =subject;Ten } One A @Override - Publicobject Invoke (Object object, method method, object[] args) - throwsThrowable the { - //we can add some of our own actions before acting on the real object. -System.out.println ("Before Rent house"); - +System.out.println ("Method:" +method); - + //when a contemporary object invokes a method of a real object, it automatically jumps to the Invoke method of the handler object associated with the proxy object . A Method.invoke (subject, args); at - //We can also add some of our own actions after acting on the real object. -System.out.println ("After Rent house"); - return NULL; - } in -}
Finally, take a look at our client class:
Public classclient{ Public Static voidMain (string[] args) {//the real object we're going to be acting forSubject Realsubject =NewRealsubject (); //we're going to proxy which real object, we'll pass the object in, and finally we'll call its method through the real object .Invocationhandler handler =NewDynamicproxy (Realsubject); /** Using Proxy's Newproxyinstance method to create our proxy object, let's take a look at its three parameters * the first parameter Handler.getclass (). getClassLoader (),
* Here we use the ClassLoader object of the handler class to load our proxy object * The second parameter Realsubject.getclass (). Getinterfaces (), we're here for proxy objects The interface provided is the interface implemented by the real object,
I'm going to represent the real object, so I can invoke the method in this set of interfaces * The third parameter handler, where we associate this surrogate object to the Invocationhandler above*/Subject Subject=(Subject) Proxy.newproxyinstance (Handler.getclass (). getClassLoader (),
Realsubject.getclass (). Getinterfaces (), handler); System.out.println (Subject.getclass (). GetName ()); Subject.rent (); Subject.hello ("World"); }}
Output Result:
$Proxy 0
Before rent housemethod:public abstract void com.xiaoluo.dynamicproxy.Subject.rent () I want to rent my houseafter rent hous Ebefore rent housemethod:public abstract void Com.xiaoluo.dynamicproxy.Subject.hello (java.lang.String) Hello: Worldafter Rent House
Results Analysis:
Let's start by looking at $Proxy 0 this thing we see, this thing is made by System.out.println (Subject.getclass (). GetName ()); This statement is printed, so why is the class name of the proxy object that we return?
Subject Subject = (Subject) proxy.newproxyinstance (Handler.getclass (). getClassLoader (), Realsubject . GetClass () . Getinterfaces (), handler);
Why can we convert it to an object of type subject? The reason is that in newproxyinstance the second parameter of this method, we give this proxy object a set of what interface, then I this proxy object will implement this set of interfaces, this Of course we can convert this proxy object coercion type to any of these sets of interfaces, because the interface here is the subject type, so it can be converted to the subject type. However, if the object being proxied does not implement any interface, what should be handled???? ---Source Explanation: Interfaces The list of interfaces for the proxy class to implement.
at the same time we must remember that the proxy object created through Proxy.newproxyinstance is an object that is dynamically generated when the JVM is running, not our invocationhandler type, nor the type of interface we define, but the A row is an object that is dynamically generated, and is named in this form, starting with $, proxy is medium, and the last number represents the label of the object .
This way, the method of the Proxied object is called by the generated new proxy object,
return a proxy instance with the specified invocation handler of a proxies class that's defined by the specified class load Er and that implements the specified interfaces.
Four, the role of dynamic agents
1, method Enhancement, from the above example we can see in the execution of the proxy object before and after the method we can do some of the actions we want to enhance the original method.
2, as a remote call, such as now has a Java interface, the implementation of this interface is deployed on other servers, in the writing of client code, there is no way to directly invoke the interface method, because the interface is not directly generated objects, this time you can consider the proxy mode (dynamic proxy), through proxy.newproxyinstance proxies A corresponding Invocationhandler object for that interface, and then encapsulates the communication details within the Invocationhandler invoke method. For specific applications, the most classic of course is the RMI of the Java Standard library.
Learn More
V. Supplementary
1. Static method in Procxy:
Method 1: The method is used to get the calling processor associated with the specified proxy object
static Invocationhandler Getinvocationhandler (Object proxy)
Method 2: The method is used to get the class object associated with the dynamic proxy class for the specified class loader and a set of interfaces
static Class Getproxyclass (ClassLoader loader, class[] interfaces)
Method 3: This method is used to determine whether the specified class object is a dynamic proxy class
Static Boolean Isproxyclass (Class cl)
Method 4: The method is used to generate a dynamic proxy class instance for the specified class loader, a set of interfaces, and the calling processor
Static Object newproxyinstance (ClassLoader loader, class[] interfaces, Invocationhandler h)
2, Proxy static method generation of dynamic proxy classes also need to be loaded through a class loader to use, and the only difference from the ordinary class is that its bytecode is generated dynamically by the JVM at runtime rather than pre-existing in any of the. class files. Each time a dynamic proxy class object is generated, you need to specify a class loader object, which is the first parameter of method 4 above, to load the generated dynamic proxy object.
java--Dynamic Agent