Design Patterns proxy mode (Proxy) and code examples Detailed

Define a proxy mode

  Define a proxy mode: for some reason you need an object to provide a proxy to control access to the object. In this case, the object does not fit or can not access a direct reference to the target object, a proxy object as an intermediary between the access and target objects, also known as commission agent model mode.

Second, why use a 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 the proxy class and delegate class implements the same interface .
  • Opening and closing principle, increased functionality: the proxy class in addition to the customer is an intermediary 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.

Third, the advantages and disadvantages of proxy mode

  The main advantage of proxy mode are:

  • Proxy mode to play a mediating role and protect the role of the target object between the client and the target object;
  • Proxy object can extend the function of the target object;
  • Client proxy mode capable of separating the target object, the coupling degree is reduced to some extent;

  The main disadvantage of proxy mode are:

  • Between the client and the target object is a proxy object to increase, will cause the slow request processing;
  • It increases the complexity of the system;

Fourth, the structure and implementation agency model

  Agents realize that there are a variety of ways, is common static agents, dynamic proxies (JDK dynamic proxy, CGLIB dynamic proxy), so the next explain one by one the three implementations.

  1, the static agent

  Static proxy mode structure is relatively simple, mostly inherited a proxy by defining abstract theme to include real theme, enabling access to the real topic. The main role of proxy mode is as follows:

  • Abstract topics (Subject) categories: real business methods and themes proxy object achieved by the interface or abstract class declaration.
  • Real theme (Real Subject) category: abstract achieve specific business topics, real object is represented by a proxy object, the object is to be the ultimate reference.
  • Proxy (Proxy) class: provides the same interface with the real theme, the interior contains a reference to the real subject, it can access, control, or extend the functionality of the real theme.

  The structure shown in Figure.

            

  code show as below:

public  class ProxyTest 
{ 
    public  static  void main (String [] args) 
    { 
        the Proxy Proxy = new new the Proxy (); 
        proxy.Request (); 
    } 
} 
// abstract relating to 
interface the Subject 
{ 
    void the Request (); 
} 
// real theme 
class RealSubject the implements Subject 
{ 
    public  void Request () 
    { 
        System.out.println ( "access real thematic approach ..." ); 
    } 
} 
// proxy
class the Proxy the implements the Subject 
{ 
    Private RealSubject RealSubject;
     public  void the Request () 
    { 
        IF (RealSubject == null ) 
        { 
            RealSubject = new new RealSubject (); 
        } 
        preRequest (); 
        realSubject.Request (); 
        postRequest (); 
    } 
    public  void preRequest ( ) 
    { 
        System.out.println ( "pretreatment prior to access real theme." ); 
    } 
    public  void postRequest () 
    {
        System.out.println ( "follow-up process after the visit real theme." ); 
    } 
}

  The output is:

Pretreatment prior to access real theme. 
Access method ... real theme 
subsequent processing after the real theme of the visit.

  Advantages and disadvantages of the static agent

  • Advantages: can be done in the function without modifying the target object, the target extensions.
  • Cons: Because the proxy object needs to implement the same interface as the target object, and so many proxy class, class too much at the same time, once the interface method for increasing the target object and proxy object must be maintained.

  2, dynamic proxy (JDK dynamic proxies)

  Agent manually create a static proxy class a lot of problems, dynamic proxies to solve this problem, one of which is comes with the JDK dynamic proxy. Acting through its own dynamic to achieve InvocationHandler, to create a dynamic proxy object for our real time running again by the JDK. Its structure is as follows:

        

  This example shows an example of a car starts, the code is implemented as follows:

// target class interface 
interface Car {
     void RUN (); 
} 

// target class 
class Benz the implements Car { 

    @Override 
    public  void RUN () { 
        System.out.println ( "Benz run up" ); 
    } 
} 

class CarUtils {
     public  static  void methodBefore () { 
        System.out.println ( "before ignition to run ... ..." ); 
    } 
    
    public  static  void methodAfter () { 
        System.out.println ( "will run up after the shift. .. ... " ); 
    } 
}

class MyInvocationHandle implements InvocationHandler{
    private Object target;
    public void setTarget(Object target) {
        this.target = target;
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            CarUtils.methodBefore();
            method.invoke(target, args);
            CarUtils.methodAfter();
            return null;
    }
}

//生产代理对象的工厂
class MyProxyFactory{
    public static Object getProxy(Object target) {
        MyInvocationHandle handle = new MyInvocationHandle();
        handle.setTarget(target);
        Object proxy = Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), handle);
        return proxy;
    }
 }

public class ProxyTest {
    public static void main(String[] args) {
      Car car = new Benz();
      Car proxy =(Car) MyProxyFactory.getProxy(car);
      proxy.run();
    }
}

   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: Type of interface to achieve the target audience, the use of generic way to confirm the type of
  • InvocationHandler指定动态处理器,The method of performing the methods of the target object, will trigger an event handler

  JDK 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 that comes with JDK dynamic proxy can only support the achievement of the Interface class.

  3, dynamic proxies (CGLIB dynamic proxies)

  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.

  We achieved by implementing dynamic proxy CGLIB MethodInterceptor, CGLIB dynamic proxy class showing the relation as shown below:

              

   code show as below:

class ArraySort{
    public void quickSort(int[] arr) {
        Arrays.sort(arr);
    }

    public void selectSort(int[] arr) {
        for (int i = 0; i < arr.length; i++) {
            for (int j = i+1; j < arr.length; j++) {
                if (arr[i] > arr[j]) {
                    int temp = 0;
                    temp = arr[i];
                    arr[i] = arr[j];
                    arr[j] = temp;
                }
            }
        }
    }

    public void bubbleSort(int[] arr) {
        for (int i = 0; i < arr.length - 1; i++) {
            for (int j = 0; j < arr.length - 1 - i; j++) {
                if (arr[j] > arr[j + 1]) {
                    int temp = 0;
                    temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;
                }
            }
        }
    }
}

class CglibInteceptor implements MethodInterceptor {

    private Object object;

    public CglibInteceptor(Object object) {
        this.object = object;
    }

    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {

        System.out.println("CGLIB动态代理执行前");
        Object result = method.invoke(object,objects);
        System.out.println("CGLIB动态代理执行后");

        return result;
    }

    public Object getProxy(){
        Enhancer enhancer = new Enhancer();
        enhancer.setCallback(this);
        enhancer.setSuperclass(object.getClass());
        return enhancer.create();
    }
}
public class CGLibProxyTest { public static void main(String[] args) { int[] arr = new int[100000]; for (int i = 0; i < arr.length; i++) { arr[i] = (int) (Math.random() * 1000); } ArraySort arraySort = new ArraySort(); arraySort = (ArraySort) new CglibInteceptor(arraySort).getProxy(); arraySort.bubbleSort(arr); arraySort.selectSort(arr); arraySort.quickSort(arr); } }

  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.

  These are the three kinds of proxy implementation. JDK dynamic proxy agent are dynamic and CGLib is the basis of Spring AOP. In the Spring of AOP programming: if the target object is added to the container for realizing the interface with JDK agent; if the target object does not implement the interface, with Cglib agent.

Guess you like

Origin www.cnblogs.com/jing99/p/12596334.html