1. What is the agent model
proxy mode refers to providing a proxy for other objects to control access to this object. In some cases, one object is not suitable or cannot directly reference another object, and the proxy object can act as an intermediary between the client class and the target object.
Baidu Encyclopedia agency model
in other words, the use of proxy objects is to enhance the main business logic without modifying the target object.
The object that the customer class really wants to access is the target object, but the object that the customer class can access is the proxy object.
The client class accesses the target object by accessing the proxy object. Of course, the proxy class and the target class should implement the same interface, that is, the functions they want to achieve are the same.
for example, there are three classes a, B and c. a used to call the methods of class C. now for some reason, class C does not allow class A to call its methods, but class B can call the methods of class C. Class a calls the methods of class C through class B. Here B is the agent of C. A accesses C through agent B, which can not only realize the function of accessing C, but also add new business functions to B
1.1 role of agency model
A. Control access
B. Enhancements
1.2 classification of agency mode
1. Static proxy
2. Dynamic agent
2. Static proxy
2.1 understanding of static agent
1) The proxy class is implemented manually. Create a java class to represent the proxy class.
2) At the same time, the target class you want to delegate is determined.
features: 1) simple implementation, 2) easy to understand.
disadvantages: when there are many target classes and agent classes in your project, there are the following disadvantages:
1) when the target class increases, the proxy class may also need to be multiplied. Too many proxy classes.
2) when the functions in your interface are added or modified, it will affect many implementation classes, target classes and agents, which need to be modified. More impact.
2.2 requirements
users need to buy USB flash disks. USB flash disk manufacturers do not receive scattered purchases separately. Users can buy them through Taobao agents or wechat merchants.
the commodities on Taobao and wechat merchants are agents of u-disk factories. They act as agents for the sales of u-disk.
User purchase -------- agents (Taobao, wechat) ---- u manufacturers (Kingston, Shandi and other different manufacturers)
design the classes required by this business:
- Both businesses and manufacturers provide the method of selling to buy u disk. Define the interface UsbSell for purchasing USB flash disk
- King ston manufacturer defines the UsbKingFactory class and implements the UsbSell interface
- San manufacturer defines the UsbSanFactory class and implements UsbSell
- Define TaoBao, the agent of TaoBao, and implement UsbSell
- WeiShang, an agent of wechat, is defined to implement UsbSell
- Define the test class, test through Taobao, and buy u disk through wechat
above, the manufacturer is the target class, the merchant is the agent, and the user is the client class, simulating the behavior of a user buying a USB flash disk. The relationship between the three: user (client) - merchant (agent) - manufacturer (target).
functions completed by proxy class:
1. Method call in target class
2. Function enhancement
2.3 code implementation
1. UsbSell interface is the function that manufacturers and agents need to realize: selling USB flash disks
2. The factory package contains the manufacturer, which is our target class
3. In shangjia package, there are proxy classes: TaoBao and WeiShang, that is, proxy classes
4. ShopMan: test class
/** * Interface: it refers to the functions that manufacturers and businesses should realize */ public interface UsbSell { //Definition method, parameter amount: indicates the quantity of a purchase, which is not used for the time being //The return value represents the price of a u disk public float sell(int amount); //There are many other methods //void print(); }
//Target class 1: Kingston manufacturers, do not accept the separate purchase of users public class UsbKingFactory implements UsbSell { @Override public float sell(int amount) { System.out.println("Method calls in the target class, useKingFactory Medium sell()"); //A 128G U SB flash disk, 85 yuan //Later, according to the amount. Different prices can be achieved return 85.0f; } }
//Taobao is a merchant, acting as the sales agent of Kingston U SB flash disk public class TaoBao implements UsbSell { //Who is the manufacturer (target class) of the business agent private UsbSell usbSell=new UsbKingFactory(); //Realize the function of selling U SB flash disk, @Override public float sell(int amount) { //Send the order to the manufacturer and tell the manufacturer that I bought the U SB flash disk and the manufacturer will deliver the goods float price = usbSell.sell(amount); //Manufacturer's price //Agent price increase function price=prce+25; After the proxy class completes the target method call, the function is enhanced //After the method call of the target class, other functions you do are enhanced System.out.println("Taobao merchants will return you a coupon or red envelope"); return price+25; } }
//Test class public class ShopMan { public static void main(String[] args) { //Create the merchant TaoBao object of the agent TaoBao taoBao = new TaoBao(); float price = taoBao.sell(1); //The merchant sold a u disk [to man] System.out.println("Buy through Taobao merchants U The unit price is: " + price); /* WeiShang weiShang = new WeiShang(); //Through the agent class to purchase u disk, other functions are added float price = weiShang.sell(1); System.out.println("The purchase price through wechat is: "+ price";*/ } }
Briefly describe the implementation steps:
1. Create an interface, define the method of selling u disk, and represent what your manufacturer and merchant do.
2. Create a manufacturer class and implement the interface in step 1
3. To create a merchant class, that is, a proxy class, you also need to implement the interface in step 1.
4. Create a client class and call the merchant's method to buy a u disk.
2.4 describe the characteristics again
1) The proxy class is implemented manually. Create a java class to represent the proxy class.
2) At the same time, the target class you want to delegate is determined.
Features: 1) easy to implement 2) easy to understand.
Disadvantages: when there are many target classes and agent classes in your project, there are the following disadvantages:
1) when the target class increases, the proxy class may also need to be multiplied. Too many proxy classes.
2) when the functions in your interface are added or modified, it will affect many implementation classes, manufacturer classes and agents, which need to be modified. More impact.
3. Dynamic agent
1. What is dynamic agent?
using the reflection mechanism of jdk, the ability to create objects is to create objects of proxy classes. Instead of creating class files. No need to write java files.
dynamic: during program execution, the object of proxy class can be created only by calling the method provided by jdk.
jdk dynamic proxy must have an interface, and the target class must implement the interface. If there is no interface, cglib dynamic proxy needs to be used
2. What can dynamic agents do
you can enhance your function code in the agent without changing the function of the original target method.
Meaning in program development.
for example, in your project, there is a function written by others (other departments of the company and people from other groups). You can use:
GongNeng.class , GongNeng gn = new GongNeng (), gn.print();
you find that this function still has shortcomings and can not fully meet the needs of my project. I need to be in GN After print() is executed, you need to add code yourself. We don't have source code, and we can't change other people's code. We use proxy to implement GN When print () is called, add your own code without changing the original GongNeng file.
3. Dynamic agent characteristics
even if there are many target classes in dynamic proxy, 1) the number of proxy classes can be small, and 2) when you modify the methods in the interface, the proxy class will not be affected.
Dynamic proxy: used during program execution jdk Create a proxy class object and dynamically specify the target class to proxy. In other words: a dynamic proxy is a creation java The ability of objects so that you don't have to create TaoBao Class, you can create a proxy class object. stay java In, to create an object: 1.Create class files, java File compiled as class 2.Use the construction method to create the object of the class.
4. Implementation of JDK dynamic agent
jdk dynamic proxy: must have interface
jdk Implementation of dynamic agent Reflection package java.lang.reflect , There are three classes: InvocationHandler , Method, Proxy. **
1)InvocationHandler interface (calling processor): just one method, invoke()
invoke():Represents the function code to be executed by the proxy object. The functions to be completed by your proxy class are written in invoke()Method. Functions completed by proxy class: 1. Call the target method and execute the function of the target method 2. Function enhancement: when the target method is called, the function is added. Method prototype: public Object invoke(Object proxy, Method method, Object[] args) throws Throwable; Parameters: Object proxy: jdk Create a proxy object without assignment. Method method: Methods in the target class, jdk provide method Object Object[] args: Parameters of the method in the target class, jdk Provided. InvocationHandler Interface: indicates what your agent wants to do. How to use it? 1.Create class implementation interface InvocationHandler 2.rewrite invoke()Method, write the functions to be completed by the proxy class in the original static proxy here.
2) Method class: represents the method, specifically the method in the target class.
Function: through Method Can execute a method of a target class, Method.invoke(); method.invoke(Target object, parameter of method) Object ret = method.invoke(service2, "Li Si"); explain: method.invoke()Is used to execute**target**Method, which is equivalent to that in static proxy //Send the order to the manufacturer and tell the manufacturer that I bought the u disk and the manufacturer will deliver the goods float price = factory.sell(amount); //Manufacturer's price.
3) Proxy class: the core object to create proxy objects. Previously created objects were all constructors of the new class ()
Now we use the method of Proxy class instead of new.
Method: static method newProxyInstance() The function is to create a proxy object, which is equivalent to that in a static proxy TaoBao taoBao = new TaoBao(); Parameters: 1. ClassLoader loader Class loader, which is responsible for loading objects into memory. Get the of an object using reflection ClassLoader: class a , a.getCalss().getClassLoader(), Classloader for target object 2. Class<?>[] interfaces: Interface, the interface implemented by the target object, is also obtained by reflection. Factory.getClass().getInterFaces() 3. InvocationHandler h : Written by ourselves, the functions to be completed by the proxy class. Return value: the proxy object Method prototype public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)
Specific implementation steps
1. Create an interface and define the functions to be completed by the target class 2. Create target class implementation interface 3. establish InvocationHandler Interface implementation class, in invoke Method to complete the function of the proxy class 1.Call target method 2.Enhancements 4.use Proxy Class to create a proxy object. And convert the return value to the interface type.
5. Code implementation dynamic proxy
* //Indicates the functions that manufacturers and businesses should realize public interface UsbSell { //Definition method, parameter amount: indicates the quantity of a purchase, which is not used for the time being //The return value represents the price of a u disk public float sell(int amount); //There are several other methods //void print(); } //Target category: Kingston manufacturer, which does not accept separate purchase by users public class UsbKingFactory implements UsbSell { @Override public float sell(int amount) { //Target method System.out.println("Executed in target class sell()Target method, useKingFactory Medium sell()"); //A 128G U SB flash disk, 85 yuan //Later, according to the amount. Different prices can be achieved return 85.0f; } }
//The InvocationHandler interface must be implemented to complete the functions to be realized by the proxy class (calling the target method and enhancing functions) public class MySellHandler implements InvocationHandler { //The object defining the dynamic target class is passed in by the construction method private Object target=null; //Dynamic proxy, the target object is active, not fixed, and needs to be passed in, // Create an agent for whoever is passed in public MySellHandler(Object target) { //Assign a value to the target object this.target = target; } /** * invoke():Represents the function code to be executed by the proxy object. The functions to be completed by your proxy class are written in the invoke() method. * Functions completed by proxy class: * 1. Call the target method and execute the function of the target method * 2. Function enhancement: when the target method is called, the function is added. * * @param proxy jdk Create a proxy object without assignment. * @param method The method in the target class. The jdk provides the method object * @param args Parameters of methods in the target class, provided by jdk. * @return * @throws Throwable */ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //Receive the return value after the execution of the target method Object res =null; //Send the order to the manufacturer and tell the manufacturer that I bought the U SB flash disk and the manufacturer will deliver the goods //float price = factory.sell(amount); // Manufacturer's price System.out.println("before"); res = method.invoke(target, args); //Method instead of calling the target method, the target class is created dynamically System.out.println("after"); //Prove that the previous code has called the method in the target class //Agent price increase function price=prce+25; After the proxy class completes the target method call, the function is enhanced //After the method call of the target class, other functions you do are enhanced System.out.println("Taobao merchants will return you a coupon or red envelope"); // return price+25; if (res!=null) { float price= (float) res+25; res=price; } //Add new features// return res; } }
/** Proxy Class: the core object to create a proxy object. Previously created objects were all constructors of the new class () Now we use the method of Proxy class instead of new. Method: static method newProxyInstance() The function is to create a proxy object, which is equivalent to Taobao in static proxy. Taobao = new taobao(); Parameters: 1. ClassLoader loader The class loader of the target object is responsible for loading the object into memory. Use reflection to get the ClassLoader of the object: Class A, a. getcalss() Getclassloader(), class loader of the target object 2. Class<?>[] interfaces: Interface, the interface implemented by the target object, is also obtained by reflection. factory.getClass().getInterfaces() 3. InvocationHandler h : Written by ourselves, the functions to be completed by the proxy class. Return value: the proxy object */ public class MainShop { public static void main(String[] args) { // Use the static method of Proxy class to create Proxy object. And convert the return value to the interface type. //1. Create object of target class UsbSell factory = new UsbKingFactory(); //2. Create the InvacationHandler object and call the method. The function is enhanced // InvacationHandler handler = new MySellHandler(factory); //3. Dynamically create a proxy object for the factory, and convert its return value to the interface type (convenient for calling the methods in the target class) UsbSell proxy= //The return value is the proxy object TaoBao (UsbSell) Proxy.newProxyInstance(factory.getClass().getClassLoader(), factory.getClass().getInterfaces(), new MySellHandler(factory)); System.out.println("proxy = " + proxy.getClass().getName()); //proxy = com.sun.proxy.$Proxy0 must be the object type created by the dynamic proxy of JDK //Through proxy objects, methods are called layer by layer float price = proxy.sell(1); System.out.println(" Call the method through the dynamic proxy object: price= " + price); } }
4. cgLib agent
CGLIB(Code Generation Library) is an open source project. It is a powerful, high-performance and high-quality code generation class library. It can extend Java classes and implement Java interfaces at run time. It is widely used by many AOP frameworks, such as Spring AOP.
using JDK Proxy to implement Proxy requires that the target class and Proxy class implement the same interface. If the target class does not have an interface, it cannot be implemented in this way.
but for classes without interfaces, to create dynamic proxies for them, we need to use cglib to implement them. The generation principle of cglib agent is to generate the subclass of the target class, and the subclass is enhanced. This subclass object is the proxy object. Therefore, using cglib to generate dynamic proxy requires that the target class must be inherited, that is, it cannot be final. Cglib is often used in frameworks, such as Spring, Hibernate, etc. The agent efficiency of cglib is higher than that of Jdk. yes
It is not used in the general development of cglib. Just make an understanding.