catalogue
2.1. 1 static proxy implementation
2.2. 1 several ways of dynamic agent implementation
2.2. 2. Implement dynamic agent
1 Preface
Proxy mode: it refers to providing a proxy for other objects to control access to this object. In some cases, an object is not suitable or can not directly reference another object, and the proxy object can play an intermediary role between the customer class and the target object.
The proxy object is used 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 what the customer can access is the proxy object. The customer class accesses the target object by accessing the proxy class.
effect:
1 function enhancement: you have added additional functions to your original functions. The newly added functions are called function enhancement
2 control access: the proxy class does not allow you to access the target
2. Agency mode
2.1 static agent
1) The proxy class is implemented manually
2) The objects you need to proxy are determined
2.1. 1 static proxy implementation
Step 1: define an interface for selling u disks
Step 2: create a manufacturer's class to implement the method of selling u disks in step 1
Step 3: create a merchant (agent) and implement the interface in step 1
Step 4: create a client class and call the merchant method to buy u disk
Code implementation:
Step 1: define an interface for selling u disks
public interface UsbSell { /** * Define a method that manufacturers and businesses should use to complete the function * @param amount Quantity purchased * @return */ float sell(int amount); }
Step 2: create a manufacturer's class to implement the method of selling u disks in step 1
//Target manufacturers only supply to middlemen and do not want to supply to individual small businesses public class UsbFactory implements UsbSell { @Override public float sell(int amount) { //The price of a U SB flash disk is 65 yuan float price = 65.0f; return amount*price; } }
Step 3: create a merchant (agent) and implement the interface in step 1
//Agent - middleman public class TaoBao implements UsbSell { //The agent is the target manufacturer class defined by Kingston private UsbFactory usbFactory = new UsbFactory(); @Override public float sell(int amount) { //Call target method float price = usbFactory.sell(amount); price = (price + 15)*amount; return price; } }
Step 4: create a client class and call the merchant method to buy u disk
@Test public void test7(){ TaoBao taoBao = new TaoBao(); float sell = taoBao.sell(80); System.out.println("***Total amount****"+sell); //***Total amount * * * * 417200.0 }
It can be seen that when we buy u-disk through agent middlemen, each u-disk by middlemen earned a price difference of 15 yuan.
We can find that the function of price increase is performed after calling the target class. In fact, this step is equivalent to an enhancement of our function (the proxy class will be enhanced when completing the function). At the same time, we can also perform some other function enhancements, such as returning coupons or red envelopes, Any function performed after the completion of our original functions belongs to function enhancement.
Advantages and disadvantages of static agent:
Advantages: easy to realize, simple and easy to understand
Disadvantages: when the target class increases, the agent will increase. The interface function has been modified, and the merchant and agent classes have been changed
2.2 dynamic agent
Dynamic proxy: in the process of program execution, use the reflection mechanism of jdk to create proxy class objects and dynamically specify the target class to proxy. (dynamic proxy is the ability to create Java objects, which eliminates the need to create proxy class objects ourselves.)
2.2. 1 several ways of dynamic agent implementation
1 cglib dynamic proxy: cglib is a third-party tool library to create proxy objects. The principle of cglib is inheritance. Cglib creates its subclass by inheriting the target class, and rewrites the method of duplicate name in the parent class in the subclass to modify the function
Because cglib inherits and rewrites methods, the classes to be inherited and the rewritten methods cannot be final. Cglib is used in the frameworks of mybatis and spring
2 dynamic Proxy of JDK: use the classes and interfaces in java reflection package to realize the function of dynamic Proxy. Reflection package: Java lang reflect three classes: InvocationHandler, Method and Proxy
1) InvocationHandler interface (calling processor): a method invoke() Represents the function code to be executed by the proxy object. The functions to be completed by the proxy class function are written in the invoke () method.
Functions completed by proxy class:
Call the target method to perform the function of the target method
Function enhancement: when the target method is called, the function is enhanced
Method prototype:
Parameters:
Object proxy: the proxy object created by jdk without assignment
Method: the method in the target class. The jdk provides the method object
Object[] args: parameter of method in target class
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable;
2) Method: represents the of the method (the method in the target class)
Function: Method can be used to execute the Method of a target class Invoke (target object, target parameter);
Note: the invoke method here is not the same as the invoke method in the InvocationHandler class
3)Proxy class: to create a proxy object, instead of creating the object through the previous construction method of new class, the method in proxy class is used instead of new
method; Static method newProxyInstance()
Parameters:
ClassLoader class loader: the loader responsible for loading objects into memory. Use reflection to get the ClassLoader of the object (for example, class B > > b.getcalss(). Getclassloader()) and the ClassLoader of the target object
Class<?> Interface: the interface implemented by the target object, which is also obtained through reflection
InvocationHandler h: the function to be completed by the proxy class
public static Object newProxyInstance(ClassLoader loader,
Class<?> interface,InvocationHandler h)
2.2. 2. Implement dynamic agent
Step 1: create an interface and define the functions to be completed by the target class
public interface UsbSell { float sell(int amount); }
Step 2: create a target class to implement the interface
public class UsbSellFactory implements UsbSell{ @Override public float sell(int amount) { System.out.println("Enter the method executed in the target class"); return 65.0f*amount; } }
Step 3: create the implementation class of InvocationHandler interface and complete the function of the agent in the invoke method (1 call the target method 2 enhance the function)
public class SellHandle implements InvocationHandler { /** * Define a target to represent the proxy object to be passed in */ private Object taeget = null; public SellHandle(Object taeget) { //Target object this.taeget = taeget; } /** * Call processor * 1 Call target method 2 enhancements * @param proxy * @param method * @param args * @return * @throws Throwable */ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { /** * 1 Executing the target method jdk will automatically substitute the parameter args into */ Object invoke = method.invoke(taeget, args); /** * 2 Enhance the function and sell each USB flash disk with a price increase of 25 yuan */ if (invoke != null ){ Float price = (Float)invoke; int num = Integer.parseInt(args[0].toString()); price = (price + 25.0f)*num; invoke = price; } return invoke; } }
Step 4: use the static method of Proxy class to create Proxy object and convert the return value to interface type
public class MainShop { public static void main(String[] args) { //1 create target object UsbSell factory = new UsbSellFactory(); //2 create InvocationHandler object InvocationHandler handle = new SellHandle(factory); //3 Create proxy object UsbSell proxy = (UsbSell)Proxy.newProxyInstance( factory.getClass().getClassLoader(), factory.getClass().getInterfaces(), handle); //4 execution method through agent float sell = proxy.sell(10); System.out.println("Through dynamic proxy,Call method:"+sell); } }
Execution results:
Summary: the jdk dynamic proxy creates the proxy object execution method. In fact, it calls the target method in the InvocationHandler class. After calling the target method, it performs a function enhancement, and then returns a result.