java23 design patterns --- proxy mode

**

What is a proxy mode?

**
define a proxy mode: a proxy mode to an object provides a proxy object, the proxy object controlled by reference to the original object. Popular speaking agency model is our life in common intermediary.

To give an example to illustrate: If you say I want to buy a used car, a series of vehicle although I can find their own source of cars, do quality testing and other transition processes, but this was really a waste of my time and energy. I just want to buy a car just why should I do so much extra thing? So I came to buy a car through an intermediary company, they come to me to find source of cars, to help me handle the transfer of vehicle ownership process, I'm just responsible for selecting their favorite car, then pay for it. Fig expressed as follows:

Why use proxy mode?

Intermediary isolation: In some cases, a client class does not want or can not directly reference a delegate object, and the proxy class object can play the role of intermediary between the client and the delegate object class, which is a proxy class and delegate class implements the same interface.
Opening and closing principle, increased functionality: In addition to being an intermediary proxy class customer class and delegate class, we can also extend the functionality of the delegate by proxy class to add additional functionality, we only need to do this without the need to modify the proxy class then modify the delegate class, in line with the principle of opening and closing the code design. Acting principal responsible for pretreatment of the delegate messages, filter messages, forward messages to the delegate, and the subsequent handling of returned results and so on. Acting class itself does not really achieve service, but the same correlation method by calling the delegate class to provide specific services. The real business function is implemented by the delegate class, but you can add some public service before and after the execution of business functions. For example, we want to join the project cache, log these functions, we can use a proxy class to complete, and no need to open the delegate class has been packaged.
What are the agency model?
Broker mode
We have a variety of different ways to achieve the agent. If the period in accordance with agency created to classify, it can be divided into two types: static proxy, dynamic agency. Static proxy is created by the programmer or a specific tool automatically generates source code in its compilation. Before programmers run, the proxy class .class file has been created. Dynamic proxies are dynamically created by the reflection in the program is running.

1. Static Proxy

Step 1: Create service class interface

 1 package main.java.proxy;
 2 
 5 /**
 6  * @Auther: 1543057945
 7  * @Description:
 8  * @Date: 22:43 2019/5/9/18
 9  */
 8 public interface BuyHouse {
 9     void buyHosue();
10 }

Step Two: Implement Service Interface

Copy the code

 1 import main.java.proxy.BuyHouse;
 2 
 5 /**
 6  * @Auther: 1543057945
 7  * @Description:
 8  * @Date: 22:43 2019/5/9/18
 9  */
 8 public class BuyHouseImpl implements BuyHouse {
 9 
10     @Override
11     public void buyHosue() {
12         System.out.println("我要买房");
13     }
14 }

Step 3: Create a proxy class

1 package main.java.proxy.impl;
 2 
 3 import main.java.proxy.BuyHouse;
 4 
 5 /**
 6  * @Auther: 1543057945
 7  * @Description:
 8  * @Date: 22:43 2019/5/9/18
 9  */
10 public class BuyHouseProxy implements BuyHouse {
11 
12     private BuyHouse buyHouse;
13 
14     public BuyHouseProxy(final BuyHouse buyHouse) {
15         this.buyHouse = buyHouse;
16     }
17 
18     @Override
19     public void buyHosue() {
20         System.out.println("买房前准备");
21         buyHouse.buyHosue();
22         System.out.println("买房后装修");
23 
24     }
25 }

The fourth step: write test classes

import main.java.proxy.impl.BuyHouseImpl;
import main.java.proxy.impl.BuyHouseProxy;

 5 /**
 6  * @Auther: 1543057945
 7  * @Description:
 8  * @Date: 22:43 2019/5/9/18
 9  */
public class ProxyTest {
    public static void main(String[] args) {
        BuyHouse buyHouse = new BuyHouseImpl();
        buyHouse.buyHosue();
        BuyHouseProxy buyHouseProxy = new BuyHouseProxy(buyHouse);
        buyHouseProxy.buyHosue();
    }
}

Static proxy Summary:

Advantages: can be done on the target object extensions in conformity with the principle of opening and closing.

Cons: We have had to create for each service proxy class, heavy workload and difficult to manage. Once changed while the interface, the proxy class have to be amended accordingly.

**

2. Dynamic Proxy

**
  In the dynamic proxy, we no longer need to manually create a proxy class, we only need to write a dynamic processor on it. True to create a dynamic proxy object for us to run again when the JDK.

** italic style first step: writing dynamic processor

 1 package main.java.proxy.impl;
 2 
 3 import java.lang.reflect.InvocationHandler;
 4 import java.lang.reflect.Method;
 5 
 5 /**
 6  * @Auther: 1543057945
 7  * @Description:
 8  * @Date: 22:43 2019/5/9/18
 9  */
11 public class DynamicProxyHandler implements InvocationHandler {
12 
13     private Object object;
14 
15     public DynamicProxyHandler(final Object object) {
16         this.object = object;
17     }
18 
19     @Override
20     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
21         System.out.println("买房前准备");
22         Object result = method.invoke(object, args);
23         System.out.println("买房后装修");
24         return result;
25     }
26 }

Step two: write test classes

 1 package main.java.proxy.test;
 2 
 3 import main.java.proxy.BuyHouse;
 4 import main.java.proxy.impl.BuyHouseImpl;
 5 import main.java.proxy.impl.DynamicProxyHandler;
 6 
 7 import java.lang.reflect.Proxy;
 8 
 5 /**
 6  * @Auther: 1543057945
 7  * @Description:
 8  * @Date: 22:43 2019/5/9/18
 9  */
14 public class DynamicProxyTest {
15     public static void main(String[] args) {
16         BuyHouse buyHouse = new BuyHouseImpl();
17         BuyHouse proxyBuyHouse = (BuyHouse) Proxy.newProxyInstance(BuyHouse.class.getClassLoader(), new
18                 Class[]{BuyHouse.class}, new DynamicProxyHandler(buyHouse));
19         proxyBuyHouse.buyHosue();
20     }
21 }

Copy the code
Note that the Proxy.newProxyInstance () method takes three parameters:

ClassLoader loader: Specifies the current target object using the class loader, the loader is to obtain a fixed
Class [] interfaces <?>: Specifies the type of interface to achieve the target object, using the generic type Checkout
InvocationHandler: specify dynamic processor when the target object execution method, the method will trigger an event handler
dynamic proxy summary: Although compared to the static agent, the agent significantly reduces the dynamic of our development tasks, while reducing dependence on the business interface, reducing the degree of coupling. But there is still a little bit of regret at, that is, it still can not shake off the shackles only supports interface agent, because its design is destined to regret this. Recall that inheritance graph dynamically generated proxy class, they have been destined to have a common parent class called Proxy. Java inheritance mechanism destined to these dynamic proxy class were unable to achieve dynamic proxy class, because multiple inheritance in Java will not work in nature. There are many bars reasons, one can negate the need for a proxy class, but equally there are some reasons to believe that support dynamic proxy class better shape. Division of interfaces and classes, this is not very obvious, but in Java to become so refinement. If only declarations of methods are defined and whether to consider from, there is a hybrid of the two, its name is an abstract class. Abstract achieve dynamic proxy class, I believe it has intrinsic value. In addition, there are some left over by history class, because they will not implement any interfaces and dynamic proxy from forever missed. So many, I had to be a little regret. However, it is not perfect does not mean not great, a great nature, Java dynamic proxy is the rank and file cases.

**

3.CGLIB agent

**
the JDK dynamic proxy class needs to implement the business methods defined by the interface, there is no interface for the class, and how to achieve it dynamic proxy, which requires a CGLib. CGLib with a very bottom of the byte code technology, the principle is to create a subclass of the class bytecode technique, and the method call interception techniques to intercept all the parent class method in the subclass, the flow cross weaving logic . However, because the use of inheritance, it can not be modified on the final proxy class. JDK dynamic proxy agent are dynamic and CGLib is the basis of Spring AOP.

Step 1: Create a proxy class CGLIB

 1 package dan.proxy.impl;
 2 
 3 import net.sf.cglib.proxy.Enhancer;
 4 import net.sf.cglib.proxy.MethodInterceptor;
 5 import net.sf.cglib.proxy.MethodProxy;
 6 
 7 import java.lang.reflect.Method;
 8 
 5 /**
 6  * @Auther: 1543057945
 7  * @Description:
 8  * @Date: 22:43 2019/5/9/18
 9  */
14 public class CglibProxy implements MethodInterceptor {
15     private Object target;
16     public Object getInstance(final Object target) {
17         this.target = target;
18         Enhancer enhancer = new Enhancer();
19         enhancer.setSuperclass(this.target.getClass());
20         enhancer.setCallback(this);
21         return enhancer.create();
22     }
23 
24     public Object intercept(Object object, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
25         System.out.println("买房前准备");
26         Object result = methodProxy.invoke(object, args);
27         System.out.println("买房后装修");
28         return result;
29     }
30 }

Step 2: Create a test class

 1 package dan.proxy.test;
 2 
 3 import dan.proxy.BuyHouse;
 4 import dan.proxy.impl.BuyHouseImpl;
 5 import dan.proxy.impl.CglibProxy;
 6 
 5 /**
 6  * @Auther: 1543057945
 7  * @Description:
 8  * @Date: 22:43 2019/5/9/18
 9  */
12 public class CglibProxyTest {
13     public static void main(String[] args){
14         BuyHouse buyHouse = new BuyHouseImpl();
15         CglibProxy cglibProxy = new CglibProxy();
16         BuyHouseImpl buyHouseCglibProxy = (BuyHouseImpl) cglibProxy.getInstance(buyHouse);
17         buyHouseCglibProxy.buyHosue();
18     }
19 }

CGLIB Agent Summary: higher performance dynamic proxy objects to create a dynamic proxy object CGLIB than JDK created, but the time it takes to create a proxy object CGLIB much more than the JDK. There is no need to create frequent target for a single case, because the object with CGLIB the right, and vice versa using JDK way to be more appropriate. And because CGLib method because it is dynamically created subclasses for the final method can not be modified agent.

Published 34 original articles · won praise 6 · views 3659

Guess you like

Origin blog.csdn.net/qq_35986709/article/details/90321375