The difference between dynamic agent proxy and Cglib

Source: Internet
Author: User
Tags abstract bind constructor static class throwable firewall

Yesterday was asked about the difference between dynamic agents and cglib, and quickly review:

what is an agent. static Proxy and dynamic proxy static proxy instance JDK Dynamic Proxy instance CGLib Introduction CGLib and JDK dynamic agent differences

Proxy mode is a common pattern in Java, the English name is a proxy or surrogate, the intention of the agent is that one person on behalf of another person, or an institution on behalf of another agency, to take action, so the agent and real life intermediary has a lot of similar, you buy a house, sell a house, Can operate on their own, but need to understand and buy and sell property-related details, such as the deed, and find an intermediary, do not care about these and the sale of real estate is not directly related to the middle details, only care about the business itself.

static proxy UML class diagram


roles included in the pattern and their responsibilities

Subject: Abstract topic role, abstract topic class can be abstract class, or interface, is a most common type of business definition, no special requirements.

Realsubject: The specific subject role, also called the delegated role, the agent role. Are the specific performers of the business logic.

Proxy: Agent topic role, also known as Delegate class, proxy class. It brings all the methods defined by the abstract topic class to the specific theme role, and does preprocessing and aftercare before and after the specific topic roles are processed. (The simplest, such as a print log):

Subject:

/**

 * Abstract theme, define main function

 *

/publicinterface Subject {

   publicvoid operate ();

}

Realsubject:

/**

 * Specific Topics

 *

/Publicclass Realsubject implements subject{

 

   @Override

   publicvoid operate () {

        System.out.println ("Realsubject operatestarted ...");}


Proxy class:

/**

 * proxy class */

Publicclass Proxy implements subject{

 

   private Subject Subject;

 

   Public Proxy (Subject Subject) {

        this.subject = Subject;

   }

 

   @Override

   publicvoid operate () {

        System.out.println ("before operate ...");

        Subject.operate ();

        SYSTEM.OUT.PRINTLN ("After operate ...");}


Client:

/**
 * Client * *
publicclass Client {
   /**
    * @param args *
   /publicstaticvoid main (string[] args ) {
        Subject Subject = new Realsubject ();
        Proxy proxy = new proxy (subject);
        Proxy.operate ();
   }
}





The application of proxy mode is summarized as follows: The proxy class is mainly responsible for preprocessing the message, filtering the message, forwarding the message to the delegate class, and processing the message afterwards.

The use of proxy mode can be divided into the following types (from GOF):

(1) Remote Proxy---A remotely proxy provides a local representative for the object in a different address space. For a local proxy object, typical examples such as RMI, the Ejb,local Bean provides a stub for the remote interface object

(2) Virtual proxy –a creates expensive objects on demand. Allow objects with large memory overhead to be created when needed. It is only created when we really need this object.

The

   virtual proxy mode is a memory-saving technique that suggests creating objects that are very memory-intensive or complex to handle when you defer creating such objects until you use them. In a particular application, the functions of different parts are made up of different objects, and when the application is launched, all objects are not immediately used. In this case, the virtual proxy pattern suggests delaying the creation of the object until the application needs it. Objects are created when the first reference is applied and the same instance can be reused. The advantages and disadvantages of this method coexist.

Advantages:

The advantage of this approach is that when an application starts, it accelerates application startup because it does not require all objects to be created and loaded.

Disadvantage:

Because there is no guarantee that a particular application object will be created, any access to this object needs to be detected to verify that it is not empty (null). That is, the time-consuming of this test is the biggest drawback.

Applying the virtual proxy pattern requires designing a separate object (referred to as a virtual proxy) that has the same interface as the real object. Different customer objects can be replaced with corresponding virtual objects in the creation and use of real objects. A virtual object maintains a reference to a real object as its instance variable. Proxy objects do not automatically create real objects, call methods on the virtual proxy object when the customer needs the service of the real object, and detect whether the real object is created.

If the real object is already created, the proxy forwards the call to the real object

If the real object is not created:

1) Proxy object Create real object

2) The proxy object assigns this object to the reference variable.

3) The proxy forwards the call to the real object

According to this arrangement, verifying that the object exists and forwards the method call these details are not visible to the customer. A customer object interacts with a proxy object just like a real object. So the customer is freed from detecting whether the real object is null, and in addition, the creation of the proxy object is less time and processing complexity than creating the real object. Therefore, when the application starts, the proxy object is used instead of the real object initialization.

(3) Copy-on-write agent (Copy-on-write proxy) – Used to control the replication of objects by delaying the copying of objects until the customer really needs them. is a variant of the virtual agent.

(4) Protection agent (Protection (Access) proxy) –a Protection proxy Controls Access to the original object. Protection proxies is useful when objects should has different access rights. Provide different levels of access to target objects for different customers

(5) Cache proxy – provides temporary storage for the result of a costly operation that allows multiple customers to share results to reduce compute or network latency.

(6) Firewall proxy (Firewall proxy) – Control access to network resources and protect topics from malicious customers.

(7) Synchronous agent (Synchronizationproxy) – Provides secure access to topics in multi-threaded situations.

(8) Smart Referral agent (smart Referenceproxy)-a smart reference is a replacement for a bare pointer that performs additional actions When a object is accessed. When an object is referenced, it provides some extra action, such as logging the number of times the object is called.

(9) Complex hidden proxy (complexity Hidingproxy) – The complexity of hiding a complex set of classes and access control. Sometimes called the appearance agent (Façade proxy), it is not difficult to understand. Complex hidden proxies and appearance patterns are not the same because the proxy controls access, and the appearance pattern is not the same because the proxy controls access, while the façade mode only provides another set of interfaces.

2. Static Agent and dynamic agent

Agent is divided into static agent and dynamic agent

Depending on the period created by the agent, it can be divided into dynamic agents and static proxies:

Static Proxy: The Agent class is generated by the programmer or the automatic generation tool, and then the proxy class is compiled and run. The proxy class already exists in the. class format before the proxy class or delegate class is run.

Static proxies: Dynamically created by the reflection mechanism while the program is running.


3. Static proxy instances

Static Proxy instances:

First you need an interface:

Package Net.battier.dao;

/**
 * Define an Account interface
 * 
 * @author Administrator * */public
interface Count {
	//View account method
	public void Querycount ();

	Modify account method public
	void Updatecount ();

}
Then is the delegate class, that is, the real implementation of the interface class, the connotation of the main business logic:

Package Net.battier.dao.impl;

Import Net.battier.dao.Count;

/**
 * Delegate class (contains business logic)
 * 
 * @author Administrator * */Public
class Countimpl implements Count {

	@Override public
	void Querycount () {
		System.out.println ("View account Method ...");

	@Override public
	void Updatecount () {
		System.out.println ("Modify Account Method ...");}

}

Finally, the proxy class:

Countproxy.java package
Net.battier.dao.impl;

Import Net.battier.dao.Count;

/**
 * This is a proxy class (Enhanced Countimpl implementation Class)
 * 
 * @author Administrator * */Public
class Countproxy Implements Count {
	private countimpl Countimpl;

	/**
	 * Overrides the default constructor
	 * 
	 * @param countimpl
	 *
	/Public countproxy (Countimpl Countimpl) {
		This.countimpl = Countimpl;
	}

	@Override public
	void Querycount () {
		System.out.println ("Before transaction processing");
		The method of invoking the delegate class;
		Countimpl.querycount ();
		System.out.println ("After transaction processing");
	}

	@Override public
	void Updatecount () {
		System.out.println ("Before transaction processing");
		The method of invoking the delegate class;
		Countimpl.updatecount ();
		System.out.println ("After transaction processing");

	}

}

Run:

Package com.mahoutchina.pattern.proxy;

public class Counttest {

	/**
	 * @param args
	 *
	/public static void main (string[] args) {
		Countimpl Coun Timpl = new Countimpl ();  
        Countproxy countproxy = new Countproxy (COUNTIMPL);  
        Countproxy.updatecount ();  
        Countproxy.querycount (); 

	}

}
From the static agent, you can see:

1. Interface: The proxy class needs to implement an interface that is identical to the interface of the delegate class, so that proxy behaves in the same way as the delegate class

2. Method: Due to interface limitations, the proxy class should also have various methods in the interface, which results in code duplication

4. Dynamic Proxy Instances
The dynamic proxy class overcomes the need to inherit the interface interface of the proxy, and realizes the defect of the corresponding method.




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) is defined in this interface. method, object[] args). 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: This class is a dynamic proxy class that acts like the proxysubject in the previous example. Protected Proxy (Invocationhandler H): constructor, estimated to be used to assign values to internal H. Static class Getproxyclass (ClassLoader loader, class[] interfaces): Gets a proxy class, where loader is a 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, The returned proxy class can be used as a proxy class (you can use a method declared in the subject interface of the proxy class).

When using dynamic proxy classes, we must implement Invocationhandler, with the above code as an example:

Subject:

Public  interface Subject {
  abstract  public  void request ();

Specific Subject:
Specific role Realsubject:
public  class Realsubject implements Subject {public
  realsubject () {}  public void request () {
    System.out.println ("from real subject.");
 }

}
Agent Processor (Proxyhandler):
Import Java.lang.reflect.Method;
Import Java.lang.reflect.InvocationHandler;

Public  class Dynamicsubject implements Invocationhandler {
  private Object sub;
  Public Dynamicsubject () {} public

  dynamicsubject (Object obj) {
    sub = obj;
  }

  public object invoke (object proxy, Method method, object[] args) throws Throwable {
    System.out.println ("before call ing "  + 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:
import Java.lang.reflect.InvocationHandler;
Import Java.lang.reflect.Proxy;
Import Java.lang.reflect.Constructor;
Import Java.lang.reflect.Method;

public class Client {

  static public void main (string[] args) throws Throwable {
   Realsubject rs = new Realsubject () ; Here the proxy class
   Invocationhandler ds = new Dynamicsubject (RS) is specified;
   Class cls = Rs.getclass ();

   The following is a one-time build agent
   Subject Subject = (Subject) proxy.newproxyinstance (Cls.getclassloader (), Cls.getinterfaces (), DS);
   subject.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.





Since JDK 1.3, the Java language supports proxies directly through the three classes provided by the Java.lang.reflex library:

Java.lang.reflect.proxy,java.lang.reflect.invocationhandler and method.

The proxy class dynamically creates agent objects at run time, which is also the origin of the dynamic proxy, the following is the class diagram, the most important of which is newproxyinstance, which indicates the loader of the class that will be proxied, the business class interface, And the calling processor for the proxy class to perform the action (Invokehandler)


public static Object newproxyinstance (ClassLoader loader, class<?>[] interfaces,
Invocationhandler h)
Throws IllegalArgumentException
Parameter description:
ClassLoader Loader: Class loader
Class<?>[] Interfaces: Get all the interfaces
Invocationhandler h: Get subclass instance of Invocationhandler interface

Ps: Class Loader
In the proxy class in the Newproxyinstance () method requires an instance of the ClassLoader class, ClassLoader actually corresponds to the class loader, in Java, there are three kinds of loaders;
Booststrap ClassLoader: This loader is written in C + + and is not visible in general development;
Extendsion ClassLoader: Used to load the extension class, generally corresponding to the class in the Jre\lib\ext directory;
Appclassloader: (default) Loads the class specified by Classpath, which is most commonly used as an loader.

When the system has a proxy object, the call to the original method is first dispatched to a calling processor (invocation Handler). The Invocationhandler interface is shown in the following figure:

Code:

Interface:

Package com.mahoutchina.pattern.proxy.dynamicproxy;

Public interface Bookfacade {public
	void Addbook ();
	public void Deletebook ();
}
Actual Business class:

Package com.mahoutchina.pattern.proxy.dynamicproxy;

public class Bookfacadeimpl implements Bookfacade {

	@Override public
	void Addbook () {
		System.out.println (" Add book logic is running ... "); 
	}

	@Override public
	void Deletebook () {
		System.out.println (' Delete book logic ' is running ... ");
		
	}
	

}
Dynamic Proxy classes:

Package com.mahoutchina.pattern.proxy.dynamicproxy;

Import Java.lang.reflect.InvocationHandler;
Import Java.lang.reflect.Method;
Import Java.lang.reflect.Proxy;

public class Bookfacadeproxy implements Invocationhandler {
	private Object target;

	/**
	 * 
	 * @param target
	 * @return
	 *
	/Public Object bind (object target) {
		This.target = target;< c12/>//Gets the proxy object
		return Proxy.newproxyinstance (Target.getclass (). getClassLoader (),
				Target.getclass (). Getinterfaces (), this);
	}

	@Override Public
	object Invoke (Object proxy, Method method, object[] args)
			throws Throwable {
		object Result=null;
		System.out.println ("Proxy start ...");
		System.out.println ("Method name:" +method.getname ());
		Result=method.invoke (target, args);
		System.out.println ("Proxy end ...");
		return result;
	}

}
Test class:

Package com.mahoutchina.pattern.proxy.dynamicproxy;

public class Testproxy {

	/**
	 * @param args
	 *
	/public static void main (string[] args) {
		Bookfacadeproxy proxy = new Bookfacadeproxy ();
		Bookfacade bookproxy = (bookfacade) proxy.bind (New Bookfacadeimpl ());
		Bookproxy.addbook ();
		Bookproxy.deletebook ();
	}

}
For the JDK proxy, the following points are available:

1) Interface: For JDK proxy, the business class needs a Interface, which is also a flaw

2) The Proxy,proxy class is generated dynamically, and this class is called Proxy.newproxyinstance (Targetcls.getclassloader, Targetcls.getinterface, Invocationhander), an instance of the proxy class is generated. In fact, this proxy class is also present, not just an instance of the class. This proxy class can be saved to the hard disk.

3) Method: For each method of the business delegate class, there is no static display of the proxy class

4) Invocationhandler: When this class executes in a business delegate class, the Invoke method is called first. The Invoke method then performs the corresponding agent operation, which can realize the repackaging of the business method.

5 CGLib Introduction

The dynamic agent mechanism of JDK can only implement the class of the interface, and the class that cannot implement the interface cannot implement the dynamic proxy of the JDK, the cglib is to implement the proxy for the class, his principle is to generate a subclass for the target class, and overwrite the method implementation enhancement, but because inherit is adopted, Therefore, the final decorated class cannot be proxied .
Example

Business class:

Package Net.battier.dao;

Public interface Bookfacade {public
	void Addbook ();
}

Package Net.battier.dao.impl;

/**
 * This is an implementation class that does not implement an interface
 * 
 * @author Student * */public
class BookFacadeImpl1 {
	public void Addbook () {
		System.out.println ("general method of adding books ...");}


Agent:

Package net.battier.proxy;

Import Java.lang.reflect.Method;

Import Net.sf.cglib.proxy.Enhancer;
Import Net.sf.cglib.proxy.MethodInterceptor;
Import Net.sf.cglib.proxy.MethodProxy;

/**
 * Use cglib dynamic Agent
 * 
 * @author Student * * */Public
class Bookfacadecglib implements Methodinterceptor {
	private Object target;

	/**
	 * Create proxy object
	 * 
	 * @param target
	 * @return
	 *
	/public object getinstance (object target) { C19/>this.target = target;
		Enhancer enhancer = new enhancer ();
		Enhancer.setsuperclass (This.target.getClass ());
		callback Method
		Enhancer.setcallback (this);
		Create proxy Object
		return Enhancer.create ();
	}

	@Override
	//callback method public
	Object Intercept (Object obj, Method method, object[] args,
			methodproxy proxy) Throws Throwable {
		System.out.println ("things start");
		Proxy.invokesuper (obj, args);
		System.out.println ("End of Thing");
		return null;


	}

}
Test

Package net.battier.test;

Import NET.BATTIER.DAO.IMPL.BOOKFACADEIMPL1;
Import Net.battier.proxy.BookFacadeCglib;

public class Testcglib {public
	
	static void Main (string[] args) {
		bookfacadecglib cglib=new bookfacadecglib (); C5/>BOOKFACADEIMPL1 bookcglib= (BOOKFACADEIMPL1) cglib.getinstance (New BookFacadeImpl1 ());
		Bookcglib.addbook ();
	}
}


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.