Java Fundamentals-Dynamic agents

Source: Internet
Author: User
Tags object object what interface

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.

Invocationhandler

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 The Throwable method accepts a total of three parameters proxy: refers to the real object of our agent method: Refers to a method object that we want to invoke a real object. Args: Refers to the arguments that are accepted when a method of a real object is called

Proxy

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 function is to get a dynamic proxy object, which receives three parameters loader: a ClassLoader object, Defines which ClassLoader object is to load the generated proxy object interfaces: An array of interface objects, which means I'm going to give a set of interfaces to the object I need to proxy, if I provide a set of interfaces to it, Then the proxy object declares that the interface (polymorphic) is implemented so that I can invoke the method in this set of Interfaces H: A Invocationhandler object, which means that when I invoke the method, the dynamic proxy object To which Invocationhandler object will be associated.

Understanding dynamic Agents with examples

First define a class interface

 Public Interface subject{    publicvoid  rent ();          Public void Hello (String str);}

Next, a class is defined to implement this interface, and this class is our real object:

 Public class Implements subject{    @Override    publicvoid  rent ()    {        System.out.println ( "I want to rent my house");    }        @Override    publicvoid  hello (String str)    {        System.out.println ( "Hello:" + str);}    }

Next, 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 classDynamicproxyImplementsinvocationhandler{//This is the real object we're going to be acting for.    PrivateObject subject; //constructs a method, assigns the initial value to the real object which we want to proxy     PublicDynamicproxy (Object subject) { This. Subject =subject; } @Override Publicobject Invoke (Object object, method method, object[] args)throwsThrowable {//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 .Method.invoke (subject, args); //We can also add some of our own actions after acting on the real object.System.out.println ("After Rent house"); return NULL; }}

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 (), which we use here Handler this class of ClassLoader object 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. 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 from the console:

$Proxy 0before rent Housemethod:  Public Abstract void com.xiaoluo.dynamicproxy.Subject.rent () I want to rent my houseafter rent housebefore rent housemethod:  Public Abstract void Com.xiaoluo.dynamicproxy.Subject.hello (java.lang.String) hello:worldafter rent House

We first take a look at $Proxy 0 This thing we see that this thing is made by

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);

Maybe I thought the returned proxy object would be an object of type subject or a Invocationhandler object, but the result is not, first we explain why we can 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 to provide a set of what interface, then I this proxy object will implement this set of interfaces, this time we can of course, this proxy object coercion type into any of the set of interfaces , because the interface here is the subject type, so it can be converted to the subject type.

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, it is not our invocationhandler type, nor is it the type of the set of interfaces we define. Instead, the run is a dynamically generated object, and the naming method is in this form, starting with $, proxy is medium, and the last number represents the label of the object .

Then we'll take a look at these two sentences.

subject.rent (); Subject.hello ("World");

Here is a proxy object to invoke the implementation of the interface method, this time the program will jump to the proxy object associated with the handler invoke method to execute, and our handler object has accepted a realsubject type of parameters, This is the real object that I want to proxy, so I'm going to call the Invoke method in handler to do it:

 Publicobject Invoke (Object object, method method, object[] args)throwsThrowable {//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 .Method.invoke (subject, args); //We can also add some of our own actions after acting on the real object.System.out.println ("After Rent house"); return NULL; }

We see that we can add some of our own operations before and after the method that actually invokes the real object through the proxy object, and we see that we have a method object like this:

 Public Abstract void com.xiaoluo.dynamicproxy.Subject.rent ()  Public Abstract void Com.xiaoluo.dynamicproxy.Subject.hello (java.lang.String)

Exactly the two methods in our subject interface, which proves that when I invoke a method through a proxy object, it is actually called by the Invoke method of the handler object to which the delegate is associated, not by itself, but by proxy.

This is our Java Dynamic Agent mechanism.

The so-called dynamic Proxy is a class that is generated at runtime and you have to provide a set of interface to it when it is generated, and then the class declares that it implements these interface. You can certainly use this class instance as any of these interface. Of course, this dynamic proxy is actually a proxy, it will not do a substantial job for you, in the generation of its instance you must provide a handler, it takes over the actual work.

The Java dynamic proxy class is located under the Java.lang.reflect package, which generally involves the following two classes:

Interface Invocationhandler
  Only one method Object:invoke (Object Obj,method method, object[] args) is defined in this interface. When actually used, the first parameter, obj, generally refers to the proxy class, which method is the proxy, as in the previous example, the request (), args is the parameter array for the method. This abstract method is implemented dynamically in the proxy class.
Proxy
The class is a dynamic proxy class that acts like the proxysubject in the previous example.
Protected Proxy (Invocationhandler h)
constructor, which is estimated to be used to assign values to internal H.
Static Class Getproxyclass (ClassLoader loader, class[] interfaces)
Get a proxy class where loader is the class loader and interfaces is an array of all the interfaces owned by the real class.
Static Object newproxyinstance (ClassLoader loader, class[] interfaces, Invocationhandler h)
Returns an instance of the proxy class that can be used as a proxy class (using a method declared in the subject interface of the proxy class).

When using dynamic proxy classes, we must implement the Invocationhandler interface with the example in the first section:

//Abstract Role (previously an abstract class, which should be changed to an interface here): Public  InterfaceSubject {Abstract   Public  voidrequest ();}//specific role Realsubject: Public  classRealsubjectImplementsSubject { PublicRealsubject () {} Public  voidrequest () {System.out.println ("From real subject." ); }}//Agent Processor:ImportJava.lang.reflect.Method;ImportJava.lang.reflect.InvocationHandler; Public  classDynamicsubjectImplementsInvocationhandler {PrivateObject Sub;  PublicDynamicsubject () {} Publicdynamicsubject (Object obj) {Sub=obj; }   PublicObject Invoke (Object proxy, Method method, object[] args)throwsthrowable {System.out.println ("Before calling" +method);    Method.invoke (Sub,args); System.out.println ("After calling" +method); return  NULL ; }}

The internal property of the proxy class is the object class, which is actually assigned by the constructor of the class Dynamicsubject (object obj), and in addition, the Invoke method is implemented in the class, and the

Method.invoke (Sub,args);

In fact, it is the method that invokes the object being executed, the method parameter sub is the actual proxy object, and args is the parameter required to perform the corresponding operation of the Proxied object. With dynamic proxy classes, we can perform some related operations before or after the call.

//Client:ImportJava.lang.reflect.InvocationHandler;ImportJava.lang.reflect.Proxy;ImportJava.lang.reflect.Constructor;ImportJava.lang.reflect.Method; Public classClient {Static  Public voidMain (string[] args)throwsThrowable {Realsubject rs=NewRealsubject ();//the proxy class is specified hereInvocationhandler ds =NewDynamicsubject (RS); Class CLS=Rs.getclass (); //The following is a one-time build agentSubject Subject =(Subject) proxy.newproxyinstance (Cls.getclassloader (), Cls.getinterfaces (), DS);  Subject.request (); }}//program Run Result:Before calling Public Abstract voidsubject.request () from real Subject.after calling Public Abstract voidSubject.request ()

In this way, the Proxied object (Realsubject) can be dynamically changed at runtime, the interface that needs to be controlled (subject interface) can be changed at runtime, the control mode (Dynamicsubject Class) can also be changed dynamically, thus realizing a very flexible dynamic agent relationship.

Java Fundamentals-Dynamic agents

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.