Java Dynamic proxy mechanism and java Mechanism

Source: Internet
Author: User

Java Dynamic proxy mechanism and java Mechanism

When learning Spring, we know that Spring has two main ideas: IoC and AOP. for IoC, dependency injection is unnecessary. For Spring's core AOP, we should not only know how to use AOP to satisfy our functions, but also learn the underlying principle of AOP, which is the dynamic proxy mechanism of java, so this article is a review of the dynamic mechanism of java.

In the dynamic Proxy mechanism of java, there are two important classes or interfaces: InvocationHandler (Interface) and Proxy (Class ), this class and interface are required to implement our dynamic proxy. First, let's take a look at how the java API help documentation describes these two classes:

InvocationHandler:

InvocationHandler is the interface implemented by the invocation handler of a proxy instance. Each proxy instance has an associated invocation handler. When a method is 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 proxy class instance is associated with a handler. When we call a method through a proxy object, the call of this method will be forwarded to the InvocationHandler interface's invoke Method for calling. Let's take a look at the unique method of InvocationHandler:

Object invoke(Object proxy, Method method, Object[] args) throws Throwable

We can see that this method accepts three parameters in total. What do these three parameters represent?

Object invoke (Object proxy, Method method, Object [] args) throws ThrowableProxy:Refers to the real object we represent.Method:It refers to the Method object of a Method of the real object to be called.Args:It refers to the parameter accepted when calling a method of a real object.

If you do not understand these parameters, you can go through an instance to explain these parameters in a deeper way.

Next let's take a look at the Proxy class:

Proxy provides static methods for creating dynamic proxy classes and instances, and it is also the superclass of all dynamic proxy classes created by those methods. 

The Proxy class is used to dynamically create a Proxy object class. It provides many methods, but we use the newProxyInstance method most:

public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces,  InvocationHandler h)  throws IllegalArgumentException
Returns an instance of a proxy class for the specified interfaces that dispatches method invocations to the specified invocation handler.

The function of this method is to get a dynamic proxy object, which receives three parameters. Let's take a look at the meanings of these three parameters:

Public static Object newProxyInstance (ClassLoader loader, Class <?> [] Interfaces, InvocationHandler h) throws IllegalArgumentExceptionLoader:A ClassLoader object that defines which ClassLoader object is used to load the generated proxy objectInterfaces:An array of Interface objects indicates a set of interfaces that I will provide to the objects that I want to proxy. If I provide a set of interfaces to it, then this proxy object claims to have implemented this interface (polymorphism), so that I can call the methods in this set of interfaces.H:An InvocationHandler object indicates which InvocationHandler object will be associated when a dynamic proxy object calls a method

Well, after introducing these two interfaces (classes), let's use an instance to see what our dynamic proxy mode is like:

First, we define a Subject interface and declare two methods for it:

public interface Subject{    public void rent();        public void hello(String str);}

Next, we 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 need to define a dynamic proxy class. As mentioned above, each dynamic proxy class must implement the InvocationHandler interface, so our dynamic proxy class is no exception:

Public class DynamicProxy implements InvocationHandler {// This is the real Object private Object subject we want to proxy; // constructor, assign the initial value public DynamicProxy (Object subject) to the real Object we want to proxy) {this. subject = subject;} @ Override public Object invoke (Object object, Method method, Object [] args) throws Throwable {// you can add some System operations before proxy objects. out. println ("before rent house"); System. out. println ("Method:" + method); // when a contemporary object calls a Method of a real object, it automatically jumps to the invoke method of the handler object associated with the proxy object to call the method. invoke (subject, args); // After the proxy is a real object, we can also add some operations of our own System. out. println ("after rent house"); return null ;}}

Finally, let's take a look at our Client class:

Public class Client {public static void main (String [] args) {// the real object we want to delegate Subject realSubject = new RealSubject (); // the actual object we want to delegate, the object is passed in, and the InvocationHandler handler = new DynamicProxy (realSubject) of the method is called through the real object ); /** use the newProxyInstance method of Proxy to create our Proxy object. Let's take a look at the 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 we provide for the proxy object here is the interface implemented by the real object, indicating that what I want to proxy is the real object, in this way, I can call the Method * third parameter handler in this set of interfaces. Here we associate this Proxy object with the InvocationHandler object above */Subject subject = (Subject) Proxy. newProxyInstance (handler. getClass (). getClassLoader (), realSubject. getClass (). getInterfaces (), handler); System. out. println (subject. getClass (). getName (); subject. rent (); subject. hello ("world ");}}

Let's take a look at the console output:

$Proxy0
before rent houseMethod:public abstract void com.xiaoluo.dynamicproxy.Subject.rent()I want to rent my houseafter rent house
before rent houseMethod:public abstract void com.xiaoluo.dynamicproxy.Subject.hello(java.lang.String)hello: worldafter rent house

First, let's take a look at $ Proxy0. We can see that this is done by System. out. println (subject. getClass (). getName (); why is the class name of the proxy object returned?

Subject subject = (Subject)Proxy.newProxyInstance(handler.getClass().getClassLoader(), realSubject                .getClass().getInterfaces(), handler);

Maybe I thought the returned proxy object would be a Subject type object or an InvocationHandler object, but the result is not. First, Let's explain it.Why can we convert it to a Subject type object here?The reason is that on the second parameter of the newProxyInstance method, we provide this proxy object with a set of interfaces, so this proxy object will implement this set of interfaces, at this time, we can forcibly convert the proxy object type to any of these interfaces. Because the interface here is of the Subject type, we can convert it to the Subject type.

At the same time, we must remember that through Proxy. the proxy object created by newProxyInstance is an object dynamically generated during jvm runtime. It is neither our InvocationHandler type nor the type of the group of interfaces we have defined, instead, it is a dynamically generated object in the running mode, and the naming method is like this. It starts with $, proxy is, and the last number represents the label of the object..

Let's take a look at these two sentences.

Subject. rent ();
Subject. hello ("world ");

This is the method in the interface implemented by calling the proxy object. At this time, the program will jump to the invoke method in the handler associated with the proxy object for execution, our handler object accepts a RealSubject type parameter, indicating that the real object that I want to proxy is used, so at this time, the invoke method in handler will be called for execution:

Public Object invoke (Object object, Method method, Object [] args) throws Throwable {// you can add your own System operations before proxy objects. out. println ("before rent house"); System. out. println ("Method:" + method); // when a contemporary object calls a Method of a real object, it automatically jumps to the invoke method of the handler object associated with the proxy object to call the method. invoke (subject, args); // After the proxy is a real object, we can also add some operations of our own System. out. println ("after rent house"); return null ;}

We can see that when calling methods of real objects through proxy objects, we can add some operations before and after this method, at the same time, we can see that our method object is like this:

public abstract void com.xiaoluo.dynamicproxy.Subject.rent()public abstract void com.xiaoluo.dynamicproxy.Subject.hello(java.lang.String)

This is exactly the two methods in our Subject interface. This proves that when I call a method through a proxy object, actually, it is called by entrusting the invoke method of the handler object associated with it. Instead of calling the method by itself, it is called by proxy.

This is our java Dynamic proxy mechanism.

 

This article explains in detail the dynamic proxy mechanism in java. This knowledge point is very important, including our Spring AOP implementation through the dynamic proxy mechanism, therefore, we must understand the dynamic proxy mechanism.

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.