About three Java proxy mode

Three Java proxy mode

Proxy mode:

Proxy (Proxy) is a design pattern that provides an additional way to access the target object; that is accessed by the target through a proxy object, the benefits of doing so are: On the basis of the target object can be achieved on additional features to enhance the operation, that is extension of the target object features.
Here to use a programming idea: Do not feel free to go at someone or modify the code already written, if the need to change the modification, the method can be extended by proxy.

To give an example to illustrate the role of the agent: Suppose we wanted to buy a ticket, then the ticket is not direct, but contact cattle, to achieve the same purpose, a person is selling tickets of the target object, and other trivial things to the his agent (cattle) to resolve. This is an example of the agent thought in reality.

Fig expressed as follows:

The key point is the agent model: proxy object and the target object, a proxy object is an extension of the target object, and calls the target object.

 

A static agents (like the decorator pattern)

When using static agent, need to define interfaces or parent class is the interface to achieve the same or the same parent is inherited along with the proxy object proxy object.

For the following examples to explain:
analog save action, the definition of a save operation interface, then the target object implements the interface methods.

At this point if you use a static proxy mode, you need to also realize IUserDao interface proxy object, when calling to call the target object through the proxy object method call.
It should be noted that the proxy object and the target object to implement the same interface, and the method to call the target object by calling the same method.

/ ** 
 * Interface 
 * / 
public  interface IUserDao { 

    void Save (); 
}

  

target:

/ ** 
 * interface 
 * target object 
 * / 
public  class UserDao the implements IUserDao {
     public  void Save () { 
        System.out.println ( "already saved data ---- ----!" ); 
    } 
}

Proxy object:

/ ** 
 * proxy object, the static agent 
 * / 
public  class UserDaoProxy the implements IUserDao {
     // receiving the target object stored 
    Private IUserDao target;
     public UserDaoProxy (IUserDao target) {
         the this .target = target; 
    } 

    public  void Save () { 
        the System.out .println ( "begin transaction ..." ); 
        target.save (); // execution of the target object's method 
        System.out.println ( "commit the transaction ..." ); 
    } 
}

test:

/ ** 
 * test class 
 * / 
public  class the App {
     public  static  void main (String [] args) {
         // audiences 
        UserDao target = new new UserDao (); 

        // proxy object, the target object to the proxy object, the proxy establish relationship 
        UserDaoProxy proxy = new new UserDaoProxy (target); 

        proxy.save (); // a proxy execution method 
    } 
}

Static proxy Summary:
1. The following functions can be done without modifying the target object, the target extensions.
2. Disadvantages: Because the proxy object needs to implement the same interface as the target object, and so many proxy class, class too, at the same time, once the interface method for increasing the target object and proxy object must be maintained.

 

II. Dynamic Proxy

Dynamic proxies have the following characteristics:
1. proxy object, do not need to implement the interface;
generating 2. proxy object, using the JDK API, build dynamic proxy object in memory (we need to specify where to create a proxy object / target object implements the interface type);
3. dynamic agent also called: JDK proxy interface agent;

JDK API generated proxy object
proxy class where the package: the java.lang.reflect.Proxy
JDK achieve newProxyInstance agent only need to use the method, this method requires three parameters, the wording is complete:

static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces,InvocationHandler h )

 

Note that this is a static method in the Proxy class, and receives three parameters were as follows:

  • ClassLoader loader,: Specifies the current target object using the class loader, the loader is to obtain a fixed
  • Class<?>[] interfaces,: Type of target object implements an interface, use the generic way to confirm the type of
  • InvocationHandler h: Event processing method executed when the target object, the event handler method will be triggered, the current method will execute the target object as a parameter

Sample code:
interface class and interface implementation class, the target object is the same, do not modify, on this basis, an increase of a proxy factory class (ProxyFactory.java).

The proxy class written in this place, then the test class (need to use proxy code) to establish contacts in the target object and proxy object, then the namesake of alternative methods proxy object.

 

Acting factory class:

/ ** 
 * Create a dynamic proxy object 
 * dynamic agent does not need to implement the interface, but need to specify the interface type 
 * / 
public  class the ProxyFactory { 

    // maintain a target object 
    Private Object target;
     public the ProxyFactory (Object target) {
         the this .target = target; 
    } 

   // for generating target object proxy object 
    public Object getProxyInstance () {
         return the Proxy.newProxyInstance ( 
                target.getClass (). getClassLoader (), 
                target.getClass (). The getInterfaces (), 
                new new of InvocationHandler () { 
                    @Override 
                    publicInvoke Object (Object Proxy, Method, Method, Object [] args) throws the Throwable { 
                        System.out.println ( "begin transaction 2" );
                         // use reflective target object execution method 
                        Object the returnValue = Method.invoke (target, args); 
                        System.out.println ( "commit transaction 2" );
                         return the returnValue; 
                    } 
                } 
        ); 
    } 

}

test:

/ ** 
 * test class 
 * / 
public  class the App {
     public  static  void main (String [] args) {
         // audiences 
        IUserDao target = new new UserDao ();
         // [primitive type class cn.itcast.b_dynamic.UserDao] 
        System.out.println (target.getClass ()); 

        // target audience, create a proxy object 
        IUserDao proxy = (IUserDao) new new the ProxyFactory (target) .getProxyInstance ();
         // class $ Proxy0 memory dynamically generated proxy object 
        System.out.println (proxy.getClass ()); 

        // perform the method of the proxy object [] 
        proxy.save (); 
    } 
}

 

Summary: proxy object does not need to implement the interface, but the target object must implement the interface, or can not use dynamic proxies

 

Three .Cglib agent (Based inheritance way)

The above static and dynamic agent Proxy models are required to achieve the target object is a target object interface, but sometimes the target object is just a single object, and does not implement any interfaces,

This time can be used in a class way to achieve the target object is a subclass of agents, this method is called: Cglib agent.

Cglib agent, also known as sub-class of agents, it is to build a subclass object in memory to achieve function expansion of the target object.

  • JDK dynamic proxy there is a limit, that is, the use of dynamic proxy object must implement one or more interfaces, if you want the agent class does not implement the interface, you can use Cglib achieved;
  • Cglib is a powerful, high-performance code generator package, it can extend and run java classes implement java interface, which is widely used in many frame AOP. Such as Spring AOP and synaop, provides a method for their interception (interception);
  • Cglib underlying packet is to convert bytecode processing framework by a small block ASM bytecode and generating a new class, ASM directly discouraged. Because it requires you to be very familiar with the JVM internal structure including the format and instruction set class file.

Cglib subclass Agent Method:
1. cglib jar files need to be introduced, but the Spring core package has been included Cglib function, directly introduced into the pring-core-3.2.5.jarcan;
2. introduction of functional package, you can dynamically build the subclass in memory ;
3. Acting classes can not be final, otherwise an error;
4. If the target object is final / static, then it will not be blocked, that no additional business method executes the target object;

5. If the method is static, private proxy is not possible.

 

Target object class:

/ ** 
 * target object does not implement any interface 
 * / 
public  class UserDao { 

    public  void Save () { 
        System.out.println ( "already saved data ---- ----!" ); 
    } 
}

 

Cglib proxy factory:

/ ** 
 * Cglib subclass proxy factory 
 * UserDao to dynamically build a subclass object in memory 
 * / 
public  class the ProxyFactory the implements MethodInterceptor {
     // maintenance target object 
    Private Object target; 

    public the ProxyFactory (Object target) {
         the this .target = target ; 
    } 

    // to the target object to create a proxy object 
    public Object getProxyInstance () {
         // 1. tools 
        Enhancer EN = new new Enhancer ();
         // 2. set the parent 
        en.setSuperclass (target.getClass ());
         / / 3. set callback 
        en.setCallback (the this );
         // 4. create a subclass (proxy object) 
        return en.create (); 

    } 

    @Override 
    public Object Intercept (Object obj, Method, Method, Object [] args, MethodProxy Proxy) throws the Throwable { 
        System.out.println ( "begin transaction ..." ); 

        // method to perform target object 
        object returnValue = Method.invoke (target, args); 

        System.out.println ( "commit the transaction ..." ); 

        return returnValue; 
    } 
}

or:

/ ** 
 * Cglib subclass proxy factory 
 * UserDao to dynamically build a subclass object in memory 
 * / 
public  class the ProxyFactory {
     // maintenance target object 
    Private Object target; 

    public the ProxyFactory (Object target) {
         the this .target = target; 
    } 

    // create a proxy object to the target object 
    public Object getProxyInstance () {
         // 1. tools 
        Enhancer EN = new new Enhancer ();
         // 2. set the parent 
        en.setSuperclass (target.getClass ());
         // . 3 set callback 
        en.setCallback ( new new MethodInterceptor () {
        public Object Intercept (Object obj, Method, Method, Object [] args, MethodProxy Proxy) throws the Throwable { 
          System.out.println ( "begin transaction ..." ); 

          // execution target object method 
          Object the returnValue = Method.invoke ( target, args); 

          System.out.println ( "commit the transaction ..." ); 

          return returnValue; 
        } 
        }); 
        // 4. create a sub-class (proxy object) 
        return en.create (); 

    } 
}    

test:

/ ** 
 * test class 
 * / 
public  class the App { 

    @Test 
    public  void Test () {
         // audiences 
        UserDao target = new new UserDao (); 

        // proxy object 
        UserDao Proxy = (UserDao) new new the ProxyFactory (target) .getProxyInstance ( ); 

        // method of performing proxy object 
        proxy.save (); 
    } 
}

 

supplement:

SpringBoot mandatory use proxy Cglib

 

Summary:
  the target object into a container if there is implementation of the interface, using JDK proxies.
  If the target object does not implement the interface, agents with Cglib.  
  If the target object implements the interface, and the mandatory use of cglib proxy, the proxy will be used cglib.


  

Guess you like

Origin www.cnblogs.com/ZJOE80/p/12131291.html