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 be said, and for spring's core AOP, we not only 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.
In the dynamic agent mechanism of Java, there are two important classes or interfaces, one is Invocationhandler (Interface), the other is proxy (class), and this class and interface is necessary to implement our dynamic proxy. 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 was 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:
Object Invoke (Object proxy, Method method, object[] args) throws Throwable
We see that this method takes three parameters altogether, so what do these three parameters represent?
Object Invoke (Object proxy, method, object[] args) throws Throwableproxy: refers to the real object we represent. method: refers to the method object that we are going to call the real object of a way. 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:
public static Object newproxyinstance (ClassLoader loader, class<?>[] interfaces, Invocationhandler h) Throws IllegalArgumentException
Returns an instance of a proxy class for the specified interfaces, dispatches method invocations to the specified INVO cation 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:
public static Object newproxyinstance (ClassLoader loader, class<?>[] interfaces, Invocationhandler h) 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 that I'm going to provide a set of interfaces to the object I need to proxy, and if I provide a set of interfaces to it, then this proxy object declares that the interface is implemented (polymorphic), So I can invoke the method in this set of interfaces H: A Invocationhandler object that represents the Invocationhandler object to which the dynamic proxy object will be associated when it calls the method.
Well, after the introduction of these two interfaces (classes), let's look at an example of what our dynamic proxy pattern looks like:
First we define an interface of type subject and declare two methods for it:
Public interface subject{public void rent (); public void Hello (String str);
Next, define a class to implement this interface, this class is our real object, Realsubject class:
public class Realsubject implements subject{ @Override public void rent () { System.out.println ("I Want to rent my house "); @Override public void Hello (String str) { System.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:
public class Dynamicproxy implements invocationhandler{ //This is what we want to proxy the real object of private objects subject; constructs the method, assigns the real object which we want the proxy to assign the initial value public dynamicproxy (object subject) { this.subject = subject; } @Override Public object Invoke (Object object, method method, object[] args) throws Throwable { // We can add some of our own operation System.out.println ("before Rent House") before acting on the real object. System.out.println ("Method:" + method); when a contemporary object invokes a method of a real object, it automatically jumps to the proxy object's associated handler object's Invoke method to invoke Method.invoke (subject, args); We can also add some of our own operation System.out.println ("After the Rent house") when acting on the real object. return null;} }
Finally, take a look at our client class:
public class client{public static void Main (string[] args) { // The real object we want to proxy Subject realsubject = New Realsubject (); we want to proxy which real object, the object is passed in, and finally through the real object to invoke its method of Invocationhandler handler = new Dynamicproxy (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 (), The interface that we provide for the proxy object is the interface that the real object implements, which means that I am going to proxy the real object so that I can invoke the method in this set of interfaces * The third parameter handler, where we associate this proxy object to the top of the Invocationhandler on this object */ Subject Subject = (Subject) proxy.newproxyinstance (Handler.getclass (). getClassLoader (), Realsubject . GetClass (). Getinterfaces (), handler); System.out.println (Subject.getclass (). GetName ()); Subject.rent (); Subject.hello ("World");} }
Java-Dynamic proxy