Three proxy modes in Java and three proxy modes in Java
Article Source: http://ms.csdn.net/geek/236074
1. Proxy Mode
Proxy is a design mode that provides an additional access method to the target object, that is, access to the target object through the Proxy object. the advantage of doing so is that additional function operations can be enhanced based on the implementation of the target object, that is, the function of the target object can be extended. the idea in programming is used here: do not modify the code or method that someone else has already written. If you need to modify it, You can extend the method through proxy.
Let's take an example to illustrate the role of proxy: if we want to invite a star, we will not directly connect to the star, but contact the agent of the star to achieve the same purpose. A star is a target object. As long as he is responsible for the program in the activity, other trivial matters are handed over to his agent (agent. this is an example of proxy ideas in reality.
The diagram is as follows:
The key aspect of the proxy mode is: the proxy object and the target object. The proxy object extends the target object and calls the target object.
1. Static proxy
When using a static proxy, You need to define the interface or parent class. The proxy object and the proxy object implement the same interface or inherit the same parent class.
The following is a case study:
Simulate the Save action and define an interface for saving the action: IUserDao. java, and then the target object implements this interface method UserDao. java. If the static proxy method is used. java) also implements the IUserDao interface. call the method of the proxy object to call the target object.
It should be noted that the proxy object and the target object must implement the same interface, and then call the method of the target object by calling the same method.
Code example: interface: IUserDao. java
/*** Interface */public interface IUserDao {void save ();}
Target object: UserDao. java
/*** Interface implementation * target object */public class UserDao implements IUserDao {public void save () {System. out. println ();}}
Proxy object: UserDaoProxy. java
/*** Proxy object, static proxy */public class UserDaoProxy implements IUserDao {// receives and saves the target object private IUserDao target; public UserDaoProxy (IUserDao target) {this.tar get = target ;} public void save () {System. out. println (); target. save (); // method of executing the target object System. out. println ();}}
Test class: App. java
/*** Test class */public class App {public static void main (String [] args) {// target object UserDao target = new UserDao (); // proxy object, pass the target object to the proxy object and establish the proxy relationship UserDaoProxy proxy = new UserDaoProxy (target); proxy. save (); // The proxy method is executed }}
Static proxy summary:
1. The target function can be expanded without modifying the target object function.
2. Disadvantages:
- Because the proxy object needs to implement the same interface as the target object, there will be many proxy classes with too many classes. At the same time, once the interface is added with methods, both the target object and the proxy object must be maintained.
How can we solve the disadvantages of static proxy? The answer is dynamic proxy.
1. 2. Dynamic proxy
Dynamic proxy has the following features:
1. Proxy object, no interface required
2. The generation of proxy objects uses JDK APIs to dynamically build proxy objects in the memory (we need to specify the type of interfaces implemented by creating proxy objects/target objects)
3. Dynamic proxy is also called JDK proxy and interface proxy.
API for generating proxy objects in JDK
Package of the Proxy class: java. lang. reflect. Proxy
The JDK proxy only needs to use the newProxyInstance method, but this method needs to receive three parameters. The complete statement is as follows:
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. The method for obtaining the loader is fixed.
- Class
/*** Create a dynamic proxy Object * the dynamic proxy does not need to implement the interface, but you need to specify the interface type */public class ProxyFactory {// maintain a private Object target of the target Object; public ProxyFactory (Object target) {this.tar get = target;} // generate a Proxy Object public Object getProxyInstance () {return Proxy for the target Object. newProxyInstance (target. getClass (). getClassLoader (), target. getClass (). getInterfaces (), new InvocationHandler () {@ Override public Object invoke (Object proxy, Method method, Object [] args) throws Throwable {System. out. println (); // method of executing the target Object returnValue = method. invoke (target, args); System. out. println (); return returnValue ;}});}}
Test class: App. java
/*** Test class */public class App {public static void main (String [] args) {// target object IUserDao target = new UserDao (); // [original class cn. itcast. B _dynamic.UserDao] System. out. println (target. getClass (); // create the proxy object IUserDao proxy = (IUserDao) new ProxyFactory (target) for the target object ). getProxyInstance (); // class $ Proxy0 dynamically generated proxy Object System in memory. out. println (proxy. getClass (); // execution method [proxy object] proxy. save ();}}
Summary:
The proxy object does not need to implement interfaces, but the target object must implement interfaces. Otherwise, dynamic proxy cannot be used.
1.3.Cglib proxy
The above static proxy and dynamic proxy modes both require that the target object be the target object that implements an interface, but sometimes the target object is only a separate object and does not implement any interfaces, in this case, you can use the method class of the target object subclass to implement proxy. This method is called Cglib proxy.
Cglib proxy, also known as subclass proxy, is used to build a subclass object in the memory to expand the function of the target object.
- JDK's dynamic proxy has a restriction that the object using dynamic proxy must implement one or more interfaces. If you want to implement a class without an interface, you can use Cglib.
- Cglib is a powerful and high-performance code generation package. It can expand java classes and implement java interfaces at runtime. it is widely used by many AOP frameworks, such as Spring AOP and synaop, to provide them with interception (interception) of methods)
- At the underlying layer of the Cglib package, a small block bytecode Processing Framework (ASM) is used to convert bytecode and generate a new class. you are not encouraged to use ASM directly because it requires you to be familiar with the JVM internal structure, including the class file format and instruction set.
Cglib subclass proxy implementation method:
1. Need to introduce cglib jar file, but Spring core package has included Cglib function, so directly introduce pring-core-3.2.5.jar.
2. After the function package is introduced, you can dynamically build child classes in the memory.
3. the proxy class cannot be final; otherwise, an error is returned.
4. If the method of the target object is final/static, it will not be intercepted, that is, it will not execute additional business methods of the target object.
Sample Code:
Target object class: UserDao. java
/*** Target object, no interface */public class UserDao {public void save () {System. out. println () ;}} Java learning exchange QQ group: 589809992 let's learn Java together!
Cglib proxy Factory: ProxyFactory. java
/*** Cglib subclass proxy factory * dynamically constructs a subclass Object */public class ProxyFactory implements MethodInterceptor for UserDao in memory. {// maintains the private Object target of the target Object; public ProxyFactory (Object target) {this.tar get = target;} // create a proxy Object public Object getProxyInstance () {// 1. tool class Enhancer en = new Enhancer (); // 2. set the parent class en. setSuperclass (target. getClass (); // 3. set the callback function en. setCallback (this); // 4. create a subclass (proxy object) return en. create () ;}@ Override public Object intercept (Object obj, Method method, Object [] args, MethodProxy proxy) throws Throwable {System. out. println (); // method of executing the target Object returnValue = method. invoke (target, args); System. out. println (); return returnValue ;}}
Test class:
/*** Test class */public class App {@ test public void Test () {// target object UserDao target = new UserDao (); // proxy object UserDao proxy = (UserDao) new ProxyFactory (target ). getProxyInstance (); // method of executing the proxy object proxy. save ();}}
In Spring's AOP programming:
If the target object to be added to the container has an implementation interface, use the JDK proxy.
If the target object does not implement the interface, use the Cglib proxy.