Agency model of Han Shunping's design model

Keywords: Java Design Pattern

catalogue

1, Proxy mode (Proxy)

Basic introduction

  2, Static proxy

2.1 basic introduction

2.2 application examples

2.3 advantages and disadvantages of static agent  

3, Dynamic agent

3.1 basic introduction

3.2 API for generating proxy objects in JDK

3.3 dynamic agent application examples

4, Cglib agent

4.1 basic introduction

4.2 implementation steps of cglib agent mode

4.3 application example of cglib proxy mode

5, Introduction to several common agent modes - several variants

1, Proxy mode (Proxy)

Basic introduction

(1) Proxy mode: provides an avatar for an object to control access to the object. That is to access the target object through the proxy object. The advantage of this is that additional function operations can be enhanced on the basis of the implementation of the target object, that is, the function of the target object can be extended.

(2) The proxied object can be a remote object, an object with high creation cost, or an object requiring security control.

(3) The agent mode has different forms, mainly including three kinds of static agent, dynamic agent (JDK agent, interface agent) and Cglib agent (you can dynamically create objects in memory without implementing interfaces. It belongs to the category of dynamic agent).

(4) Schematic diagram of agent mode

  2, Static proxy

2.1 basic introduction

When using a static proxy, you need to define an interface or parent class. The proxy object (i.e. the target object) implements the same interface or inherits the same parent class with the proxy object.

2.2 application examples

(1) Define an interface: ITeacherDao

(2) The target object TeacherDAO implements the interface ITeacherDAO

(3) Using the static proxy method, you need to implement ITeacherDAO in the proxy object TeacherDAOProxy

(4) When called, the target object is called by calling the method of the proxy object

(5) Special reminder: the proxy object and the target object should implement the same interface, and then call the method of the target object by calling the same method

Train of thought analysis diagram (class diagram)

 

code implementation  

package com.atguigu.proxy.staticproxy;

//Interface
public interface ITeacherDao {
    public void teach();//Teaching methods
}
package com.atguigu.proxy.staticproxy;

/**
 * @author wjd
 * @date 2021 At 0:10 on September 21
 */
public class TeacherDao implements ITeacherDao {

    @Override
    public void teach() {
        System.out.println(" The teacher is teaching... ");
    }
}
package com.atguigu.proxy.staticproxy;

/**
 * @author wjd
 * @date 2021 At 0:11 on September 21
 */
//Proxy object, static proxy
public class TeacherDaoProxy implements ITeacherDao {
    ITeacherDao target;//Target object, aggregated through interface

    //constructor 
    public TeacherDaoProxy(ITeacherDao target) {
        this.target = target;
    }

    @Override
    public void teach() {
        System.out.println("The static agent starts and completes some operations...");//method
        target.teach();
        System.out.println("Static proxy submission...");//method
    }
}
package com.atguigu.proxy.staticproxy;

/**
 * @author wjd
 * @date 2021 September 21, 2014 0:14
 */
public class Client {
    public static void main(String[] args) {
        //Create target object (proxied object)
        TeacherDao teacherDao = new TeacherDao();

        //Create a proxy object and pass the proxy object to the proxy object at the same time
        TeacherDaoProxy teacherDaoProxy = new TeacherDaoProxy(teacherDao);

        //Through the proxy object, call the method to the proxy object
        //That is, the method of the proxy object is executed, and the proxy object calls the method of the target object
        teacherDaoProxy.teach();
    }
}

2.3 advantages and disadvantages of static agent  

(1) Advantages: the target function can be extended through the proxy object without modifying the function of the target object.

(2) Disadvantages: because the proxy object needs to implement the same interface as the target object, there will be many proxy classes.

(4) Once a method is added to the interface, both the target object and the proxy object must be maintained.

3, Dynamic agent

3.1 basic introduction

(1) The proxy object does not need to implement the interface, but the target object must implement the interface, otherwise the dynamic proxy cannot be used.

(2) The generation of proxy object is to dynamically build proxy object in memory by using JDK API.

(3) Dynamic agent is also called JDK agent and interface agent.

3.2 API for generating proxy objects in JDK

(1) Package of proxy class: java.lang.reflect.Proxy

(2) The JDK implementation agent only needs to use the newProxyInstance method, but this method needs to receive three parameters. The complete writing method is:

static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces,InvocationHandler h )

3.3 dynamic agent application examples

Application example requirements

Improve the previous static proxy to dynamic proxy mode (i.e. JDK proxy mode)

Train of thought diagram (class diagram)

 

code implementation

package com.atguigu.proxy.dynamicproxy;

//Interface
public interface ITeacherDao {
    public void teach();//Teaching methods
    public void sayHello(String name);
}
package com.atguigu.proxy.dynamicproxy;

/**
 * @author wjd
 * @date 2021 At 0:10 on September 21
 */
public class TeacherDao implements ITeacherDao {

    @Override
    public void teach() {
        System.out.println(" The teacher is teaching... ");
    }

    @Override
    public void sayHello(String name) {
        System.out.println("Hello," + name);
    }
}
package com.atguigu.proxy.dynamicproxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * @author wjd
 * @date 2021 September 21, 2008 0:28
 */
public class ProxyFactory {
    //Maintain a target Object (proxied Object), Object
    Object target;

    //Constructor to initialize the target
    public ProxyFactory(Object target) {
        this.target = target;
    }

    //Generate a proxy object for the target object (proxy object)
    public Object getProxyInstance() {
        //explain
		/*
		 *  public static Object newProxyInstance(ClassLoader loader,
                                          Class<?>[] interfaces,
                                          InvocationHandler h)

            //1. ClassLoader loader :  Specifies the class loader used by the current target object, and the method to get the loader is fixed
            //2. Class<?>[] interfaces: The interface type implemented by the target object, and use the generic method to confirm the type
            //3. InvocationHandler h : In event processing, when executing the method of the target object, the event processor method will be triggered, and the currently executed target object method will be passed in as a parameter
		 */
        return Proxy.newProxyInstance(target.getClass().getClassLoader(),
                target.getClass().getInterfaces(),
                new InvocationHandler() {
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        System.out.println("JDK Agent start~~");
                        //The reflection mechanism calls the method of the target object
                        Object returnVal = method.invoke(target, args);
                        System.out.println("JDK Proxy submission");
                        return returnVal;
                }
        });
    }
}
package com.atguigu.proxy.dynamicproxy;

/**
 * @author wjd
 * @date 2021 September 21, 2007 0:37
 */
public class Client {
    public static void main(String[] args) {
        //Create target object
        ITeacherDao target = new TeacherDao();

        //Create a proxy object for the target object, which can be converted to ITeacherDao
        ITeacherDao proxyInstance = (ITeacherDao) new ProxyFactory(target).getProxyInstance();

        // proxyInstance=class com.sun.proxy.$Proxy0 dynamically generates proxy objects in memory
        System.out.println("proxyInstance=" + proxyInstance.getClass());

        //The method of the target object is called through the proxy object
        proxyInstance.teach();
        proxyInstance.sayHello("Jack");
    }
}

4, Cglib agent

4.1 basic introduction

(1) Both static proxy and JDK proxy modes require the target object to implement an interface, but sometimes the target object is only a separate object and does not implement any interface. At this time, the target object subclass can be used to implement the proxy - this is Cglib proxy.

(2) Cglib agent is also called subclass agent. It constructs a subclass object in memory to expand the function of the target object. Some books also attribute cglib agent to dynamic agent.

(3) Cglib is a powerful high-performance code generation package. It can extend java classes and implement java interfaces at runtime. It is widely used by many AOP frameworks, such as Spring AOP, to implement method interception.

(4) How to select proxy mode in AOP programming:

1. The target object needs to implement the interface and use JDK proxy

2. The target object does not need to implement the interface and uses Cglib proxy

(5) The bottom layer of Cglib package is to convert bytecode and generate new classes by using bytecode processing framework ASM.

4.2 implementation steps of cglib agent mode

(1) You need to import the jar file of cglib

  (2) Dynamically build subclasses in memory. Note that the class of the agent cannot be final, otherwise an error will be reported

java.lang.IllegalArgumentException:

(3) If the method of the target object is final/static, it will not be intercepted, that is, additional business methods of the target object will not be executed

4.3 application example of cglib proxy mode

Application example requirements

The previous case is implemented with Cglib proxy mode

Train of thought diagram (class diagram)

package com.atguigu.proxy.cglibproxy;

import com.atguigu.proxy.dynamicproxy.ITeacherDao;

/**
 * @author wjd
 * @date 2021 At 0:10 on September 21
 */
public class TeacherDao implements ITeacherDao {

    @Override
    public void teach() {
        System.out.println(" In the teacher's teaching, use cglib Proxy, no need to implement interface... ");
    }

    @Override
    public void sayHello(String name) {
        System.out.println("Hello," + name);
    }
}
package com.atguigu.proxy.cglibproxy;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

/**
 * @author wjd
 * @date 2021 September 21, 2008 0:28
 */
public class ProxyFactory implements MethodInterceptor {
    //Maintain a target Object (proxied Object), Object
    Object target;

    //Constructor to initialize the target
    public ProxyFactory(Object target) {
        this.target = target;
    }

    //Returns a proxy object: the proxy object of the target object
    public Object getProxyInstance() {
        //1. Create a tool class
        Enhancer enhancer = new Enhancer();
        //2. Set parent class
        enhancer.setSuperclass(target.getClass());
        //3. Set callback function
        enhancer.setCallback(this);
        //4. Create a subclass object, that is, a proxy object
        return enhancer.create();
    }

    //Overriding the intercept method will call the method of the target object
    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        System.out.println("Cglib proxy pattern ~~ start");
        Object returnVal = method.invoke(target, objects);
        System.out.println("Cglib proxy pattern ~~ Submit");
        return returnVal;
    }
}
package com.atguigu.proxy.cglibproxy;

/**
 * @author wjd
 * @date 2021 1:09, September 21
 */
public class Client {
    public static void main(String[] args) {
        //Create target object
        TeacherDao target = new TeacherDao();

        //Gets the proxy object and passes the target object to the proxy object
        TeacherDao proxyInstance = (TeacherDao) new ProxyFactory(target).getProxyInstance();

        //Execute the method of the proxy object and trigger the concept method to call the target object
        proxyInstance.teach();
        proxyInstance.sayHello("Lilei");
    }
}

5, Introduction to several common agent modes - several variants

(1) Firewall agent

The intranet penetrates the firewall through the agent to realize the access to the public network.

(2) Cache agent

For example, when requesting resources such as picture files, go to the cache agent first. If you get the resources, ok. If you can't get the resources, go to the public network or database, and then cache.

(3) Remote agent

The local representative of the remote object, through which the remote object can be called as a local object. Remote agents communicate information with real remote objects through the network.

(4) Synchronization agent: mainly used in multithreaded programming to complete synchronization between multithreads

Synchronization agent: it is mainly used in multithreaded programming to complete the synchronization between multithreads.

Posted by ScOrPi on Mon, 20 Sep 2021 22:53:41 -0700