A dynamic proxy Java dynamic proxy mechanism of java Detailed

I. Introduction

Spring in learning, we know there are two main ideas Spring, one IoC, AOP is another, for IoC, Dependency Injection Needless to say, and for the core Spring AOP, we must not only know how through AOP to meet our function, we need to learn is how its underlying principle is a kind, but the principle is the dynamic AOP proxy mechanism java, so Benpian essays is the dynamic mechanism of java will be a review.

Two, InvocationHandler and Proxy

In java dynamic proxy mechanism, there are two important classes or interfaces, one InvocationHandler (Interface), the other is Proxy (Class), which is a class and interfaces to achieve our dynamic proxy must be used. First, let's take a look at the java API documentation is how to help these two classes are described:

InvocationHandler:

/**
 * {@code InvocationHandler} is the interface implemented by
 * the <i>invocation handler</i> of a proxy instance.
 *
 * <p>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 {@code invoke}
 * method of its invocation handler.
 *
 * @author      Peter Jones
 * @see         Proxy
 * @since       1.3
 */

invocation handler proxy object must be to achieve InvocationHandler interface.

Each agent invocation handler object has an associated. When you call a method through a proxy object, this method calls invoke the method invocation handler.

InvocationHandle the only method interfaces invoke:

/**
     * Processes a method invocation on a proxy instance and returns
     * the result.  This method will be invoked on an invocation handler
     * when a method is invoked on a proxy instance that it is
     * associated with.
     *
     * @param   proxy the proxy instance that the method was invoked on
     *
     * @param   method the {@code Method} instance corresponding to
     * the interface method invoked on the proxy instance.  The declaring
     * class of the {@code Method} object will be the interface that
     * the method was declared in, which may be a superinterface of the
     * proxy interface that the proxy class inherits the method through.
     *
     * @param   args an array of objects containing the values of the
     * arguments passed in the method invocation on the proxy instance,
     * or {@code null} if interface method takes no arguments.
     * Arguments of primitive types are wrapped in instances of the
     * appropriate primitive wrapper class, such as
     * {@code java.lang.Integer} or {@code java.lang.Boolean}.
     *
     * @return  the value to return from the method invocation on the
     * proxy instance.  */
    public Object invoke(Object proxy, Method method, Object[] args)
        throws Throwable;

The role of this method is to call processing method based on the proxy object. Look at the three parameters invoke method:

proxy: proxy object, the proxy object by calling the method

method: corresponds to the interface method invoked through a proxy object

args: passed in through a proxy object calls a method parameter

Proxy:

/**
 * {@code 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.
 */

Proxy provides static methods for creating dynamic proxy object, which is the most used method newProxyInstance.

/**
     * Returns an instance of a proxy class for the specified interfaces
     * that dispatches method invocations to the specified invocation
     * handler.
     *
     * @param   loader the class loader to define the proxy class
     * @param   interfaces the list of interfaces for the proxy class
     *          to implement
     * @param   h the invocation handler to dispatch method invocations to
     * @return  a proxy instance with the specified invocation handler of a
     *          proxy class that is defined by the specified class loader
     *          and that implements the specified interfaces
     */
    @CallerSensitive
    public static Object newProxyInstance(ClassLoader loader,
                                          Class<?>[] interfaces,
                                          InvocationHandler h)
        throws IllegalArgumentException
    {..........}

Method returns a proxy object parameter based on the interface, the proxy object method calls will be sent to the specified invocation handler. Look at the three parameters of the process:

loader: a ClassLoader object is defined to be a proxy object generated by the object ClassLoader which loaded

interfaces: an array of Interface objects to the proxy object provides a set of interfaces, if provided a set of interfaces to it, then the proxy object has stated that implements this interface (polymorphism), so that we can call this set of interface methods the

h: a InvocationHandler object when the proxy object method call, will be linked to the subject InvocationHandler

InvocationHandler interfaces and concepts introduced over the Proxy class, stroked look at the association between these two:

First obtain a proxy object by newProxyInstance Proxy class and based on the proxy object method call will trigger invoke a method invocation handler associated with the proxy object in.

By dynamic proxy mode code demonstrates what is what?

First define a proxy to the object (real object): Subject type interface declares two methods for

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

Interface implementation class RealSubject:

public class RealSubject implements Subject {
    @Override
    public  void getNews () {
        System.out.println ( "Beijing to implement a garbage classification" );
    }

    @Override
    public void hello(String str) {
        System.out.println("hello:" + str);
    }
}

Then define the proxy object:

public  class the ProxyFactory {
     // real object 
    Private Object realObj;

    public ProxyFactory(Object realObj){
        this.realObj = realObj;
    }

    / * Get the proxy object * / 
    public Object getProxyInstance () {
        Object proxyInstance = Proxy.newProxyInstance(realObj.getClass().getClassLoader(), realObj.getClass().getInterfaces(), new InvocationHandleImpl());
        System.out.println ( "acquired proxy object:" + . ProxyInstance.getClass () getName ());
         return proxyInstance;
    }

    //InvocationHandler的实现
    class InvocationHandleImpl implements InvocationHandler{

        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            System.out.println ( "invoke the proxy object:" + . Proxy.getClass () getName ());
             // add some of their operations before the agency real object 
            System.out.println ( "=== before" );
            System.out.println("method:" + method);
            InvokeResult Object = Method.invoke (realObj, args);
             // add some of their operations after the agency real object 
            System.out.println ( "the After ===" );
             return invokeResult;
        }
    }

}

test:

public class Test {
    public static void main(String[] args) {
        Subject realSubject = new RealSubject();
        The ProxyFactory the ProxyFactory = new new the ProxyFactory (RealSubject);
         // obtain the proxy object 
        Subject proxyInstance = (Subject) proxyFactory.getProxyInstance ();
         // method is based on the proxy object to call 
        proxyInstance.getNews ();
        proxyInstance.hello ( "Dynamic Agent" );
    }
}

result:

Get to the proxy object: com.sun.proxy $ Proxy0.
Invoke the proxy object: com.sun.proxy $ Proxy0.
===before
method:public abstract void com.hy.spring.service.Subject.getNews()
Beijing to implement a garbage classification
===after
Invoke the proxy object: com.sun.proxy $ Proxy0.
===before
method:public abstract void com.hy.spring.service.Subject.hello(java.lang.String)
hello: Dynamic Proxy
===after

You can see the returned proxy object class name is:. Com.sun.proxy $ Proxy0, and invocation parameters in the proxy handler invoke method is the same proxy object

Proxy.newProxyInstance proxy object is an object created dynamically generated in jvm is running, it is not our InvocationHandler type, neither that group we define the type of interface, but running is an object dynamically generated, and named way all such forms, beginning with $, proxy is, the last digit indicates the label objects .

Again to explain why the proxy object can be converted to an object of type Subject? The reason is that on the second parameter newProxyInstance this method, we give the proxy object provides a set of what the interface, the proxy, then I will achieve this set of interfaces, of course, this time we can use this proxy object mandatory conversion this set of interfaces is an arbitrary one, since the Subject the interface type, it can be converted to a type Subject.

 

When to call the real object of the method through a proxy object, we can add some of their own operations before and after the process, and we see our target of this method is as follows:

method:public abstract void com.hy.spring.service.Subject.getNews()
method:public abstract void com.hy.spring.service.Subject.hello(java.lang.String)

Our method is just two Subject interface, which also proved when to call the method through a proxy object is in fact a delegate invoke its methods associated with the invocation handler object to call, not to own real call, but by the way agents to call. This is the Java dynamic proxy mechanism.

Benpian detailed explanation of the dynamic proxy mechanism in Java, this knowledge is very, very important, including our Spring AOP it is through the mechanism of dynamic proxy to achieve, so we must be good to understand the mechanism of dynamic proxies.

reference:

Detailed java dynamic proxy mechanism

Guess you like

Origin www.cnblogs.com/zfyang2429/p/11125716.html