Three types of proxy modes for Java 1. Proxy mode
Proxy is a design pattern that provides additional access to the target object, that is, access to the target object through the proxy object. The advantage of this is that you can enhance the functionality of the target object by enhancing the functionality of the object, based on its implementation.
Here is a thought of programming: Do not arbitrarily modify the code or methods that others have written, if you need to change, you can extend the method by proxy way
The most important feature of the proxy mode is that the proxy class and the actual business class implement the same interface (or inherit the same parent class), the proxy object holds a reference to the actual object, the external invocation is the proxy object, and the actual object operation is called in the internal implementation of the proxy object.
In fact, the Java Dynamic Agent is also implemented through the Java reflection mechanism, known as an object, and then dynamically call its methods at run time, so that before and after the call to do some appropriate processing
For example, to illustrate the role of the agent: Suppose we want to invite a star, then not directly connect the star, but contact the star's agent, to achieve the same goal. A star is a target, and he only takes charge of the program in the event, and other trivial things to his agent (broker) To solve. This is an example of the idea of acting in reality.
The diagram shows the following:
The key point of the proxy mode is: The proxy object and the target object. The proxy object is an extension to the target object and the target object is called
1.1. Static Proxy
Static proxies, when used, need to define interfaces or parent classes that are implemented with the same interface or inherit the same parent class as the proxy object.
Here's an example to explain:
To simulate a save action, define an interface to save the action: Iuserdao.java, and then the target object implements the method Userdao.java for this interface, at this point, if the static proxy method is used, the proxy object (Userdaoproxy.java) The Iuserdao interface is also implemented in the call. Invokes the target object by invoking the proxy object's method.
It is important to note that the proxy object is to implement the same interface as the target object, and then invoke the method of the target object by calling the same method
code example:
Interface: Iuserdao.java
/***/Publicinterface Iuserdao {void Save ();}
Target object: Userdao.java
/***/Publicclassimplements Iuserdao {public void Save () { System.out.println ("----has saved data!----");} }
Proxy object: Userdaoproxy.java
/*** Proxy object, static proxy*/ Public classUserdaoproxyImplementsiuserdao{//receive Save target object PrivateIuserdao Target; PublicUserdaoproxy (Iuserdao target) { This. target=Target; } Public voidSave () {System.out.println ("Start transaction ..."); Target.save ();//methods for executing target objectsSYSTEM.OUT.PRINTLN ("Commit Transaction ..."); }}
Test class: App.java
/*** Test Class*/ Public classApp { Public Static voidMain (string[] args) {//target ObjectUserdao target =NewUserdao (); //Proxy object, the target object is passed to the proxy object, the agent relationship is established.Userdaoproxy proxy =NewUserdaoproxy (target); Proxy.save ();//The method that performs the proxy }}
Static Agent Summary:
1. You can extend the target function without modifying the function of the target object.
2. Disadvantages:
- Because the proxy object needs to implement the same interface as the target object, there are many proxy classes and too many classes. At the same time, once the interface is incremented, both the target object and the proxy object are maintained.
How to solve the disadvantages of static agents? The answer is that you can use dynamic proxy mode
1.2. Dynamic Agent
Dynamic agents have the following characteristics:
1. Proxy object, do not need to implement interface
2. The generation of proxy objects is the use of the JDK API to dynamically build proxy objects in memory (requires us to specify the type of interface that creates the proxy object/target object implementation)
3. Dynamic agent is also called: JDK Agent, Interface agent
API for generating proxy objects in JDK
Agent Class Package: Java.lang.reflect.Proxy
The JDK implementation agent only needs to use the Newproxyinstance method, but the method needs to receive three parameters, the complete wording is:
Static Object newproxyinstance (ClassLoader loader, class<?>[] Interfaces,invocationhandler h)
Note that this method is a static method in the proxy class, and the three parameters received are:
ClassLoader loader,
: Specifies that the current target object uses the class loader, and that the method to get the loader is fixed
Class<?>[] interfaces,
: Type of interface implemented by the target object, using generic mode acknowledgment type
InvocationHandler h
: Event handling, the method that triggers the event handler when the method of the target object is executed, passing the method of the current execution target object as a parameter
code example:
Interface class Iuserdao.java and the interface implementation class, the target object Userdao is the same, no modification. On this basis, add a proxy factory class (Proxyfactory.java), write the proxy class in this place, and then in the test class (the code that needs to use the proxy ), the contact of the target object and the proxy object is established, and then the same name method in the proxy object is substituted.
Agent Factory class: Proxyfactory.java
/*** Create dynamic proxy objects * Dynamic proxies do not need to implement interfaces, but need to specify interface types*/ Public classproxyfactory{//maintain a target object PrivateObject Target; Publicproxyfactory (Object target) { This. target=Target; } //to generate a proxy object for a target object PublicObject getproxyinstance () {returnproxy.newproxyinstance (Target.getclass (). getClassLoader (), Target.getclass (). Getinterf Aces (),NewInvocationhandler () {@Override PublicObject Invoke (Object proxy, Method method, object[] args)throwsthrowable {System.out.println ("Start Transaction 2"); //execute target object methodObject returnvalue =Method.invoke (target, args); System.out.println ("Commit TRANSACTION 2"); returnreturnvalue; } } ); }}
Test class: App.java
/*** Test Class*/ Public classApp { Public Static voidMain (string[] args) {//target ObjectIuserdao target =NewUserdao (); //"The original type class cn.itcast.b_dynamic. Userdao "System.out.println (Target.getclass ()); //to the target object, create a proxy objectIuserdao proxy = (Iuserdao)Newproxyfactory (target). Getproxyinstance (); //class $Proxy 0 dynamically generated proxy objects in memorySystem.out.println (Proxy.getclass ()); //execution Method "proxy object"Proxy.save (); }}
Summarize:
The proxy object does not need to implement the interface, but the target object must implement the interface, otherwise it cannot use the dynamic proxy
1.3.Cglib Proxy
Both the static agent and the dynamic proxy pattern above require that the target object be the target object to implement an interface, but sometimes the target object is just a separate object, and there is no interface to implement, this can be used to implement the proxy in the same way as the object subclass, this method is called: Cglib agent
Cglib Proxy, also known as the subclass Proxy, is to build a subclass object in memory to extend the functionality of the target object.
- The dynamic proxy for JDK has a limitation that an object using a dynamic proxy must implement one or more interfaces, and if you want to broker a class that does not implement an interface, you can use the Cglib implementation.
- Cglib is a powerful, high-performance code-generation package that extends Java classes and implements Java interfaces at run time. It is widely used by many AOP frameworks, such as spring AOP and SYNAOP, to provide them with methods of interception (interception)
- The bottom of the Cglib package is to convert bytecode and generate new classes by using a small block of bytecode processing framework ASM. Direct use of ASM is discouraged because it requires you to be familiar with the format and instruction set of the JVM's internal structure including the class file.
Cglib sub-Class proxy implementation method:
1. The Cglib jar file needs to be introduced, but the Cglib feature is already included in spring's core package, so it can be introduced directly pring-core-3.2.5.jar
.
2. Once the feature Pack is introduced, you can dynamically build subclasses in memory
3. The proxy class cannot be final, otherwise the error
4. If the target object's method is final/static, it will not be intercepted, i.e. the target object's additional business methods will not be executed.
code example:
Target object class: Userdao.java
/***/Publicclass Userdao {publicvoid Save () { System.out.println ("----has saved data!----");} }
Cglib Agent Factory: Proxyfactory.java
/*** Cglib sub-class agent factory * Dynamically constructs a subclass object in memory for Userdao*/ Public classProxyfactoryImplementsmethodinterceptor{//Maintaining target objects PrivateObject Target; Publicproxyfactory (Object target) { This. target =Target; } //Create a proxy object for the target object PublicObject getproxyinstance () {//1. Tool ClassEnhancer en =Newenhancer (); //2. Set the parent classEn.setsuperclass (Target.getclass ()); //3. Setting the callback functionEn.setcallback ( This); //4. Creating subclasses (proxy objects) returnen.create (); } @Override PublicObject Intercept (Object obj, Method method, object[] args, Methodproxy proxy)throwsthrowable {System.out.println ("Start transaction ..."); //methods for executing target objectsObject returnvalue =Method.invoke (target, args); System.out.println ("Commit Transaction ..."); returnreturnvalue; }}
Test class:
/** * Test class */ public class App {@Test public void
Test () {
//
target object /span> Userdao target = new Userdao (); // proxy object Userdao proxy = (Userdao)
new
Proxyfactory (target). Getproxyinstance ();
//
methods for executing proxy objects
Proxy.save (); }}
The proxy class is mainly responsible for preprocessing messages, filtering messages, forwarding messages to the target object class class, and processing messages afterwards. There is usually an association between the proxy class and the target object class class, and the object of a proxy class is associated with an object of the target object class class, and the object of the proxy class does not actually implement the service, but rather by invoking the relevant method of the object of the target object class class to provide the specific service.
In spring's AOP programming:
If the target object that joins the container has an implementation interface, use the JDK proxy
If the target object does not implement an interface, use the Cglib proxy
Reprint Address: https://www.cnblogs.com/cenyu/p/6289209.html
Java proxy mode (static agent, dynamic agent, Cglib agent) reprint