Easy-to-understand java design pattern-proxy pattern

1. What is the proxy mode

Provide a proxy object for an object, through which the access to the original object can be controlled.

Popular explanation: One by one quick connection on our computer desktop, when we click this shortcut, we indirectly access this program.

2. Static proxy

What is static? That is, before the program runs, the proxy class has been written by the programmer and the .class file is generated

The following is the simplest example, the purpose: use the chicken proxy object to help us create the chicken animal

2.1 Simple code implementation of static proxy

First, create an interface that represents all animals and specifies all behaviors of animals

public interface Animal {
    void cry();
}

Let's create an entity of the proxy object, here we take chicken as an example

public class Chick implements Animal{
    private String name;

    public Chick(String name) {
        this.name = name;
        birth(name);
    }

    private void birth(String name) {
        System.out.println("name is"+name+"the chicken was born");
    }

    @Override
    public void cry() {
        System.out.println("i am a barking"+name+"chicken");
    }
}

The following is the proxy class of the animal chicken, which also needs to implement the Animal interface

public class ProxyChick implements Animal{
    private String name;
    private Chick chick;

    public ProxyChick(String name) {
        this.name = name;
    }

    @Override
    public void cry() {
        if (chick==null){
            chick = new Chick(name);
        }
        chick.cry();
    }
}

The test uses the chicken proxy class to get the chicken

public class ProxyTest {
    public static void main(String[] args){
        ProxyChick chick = new ProxyChick("Cai Xukun");
        chick.cry();
        System.out.println("================");
        chick.cry();
    }
}

2.2 Application in java

spring's Aop

Remember aspect-oriented programming? How did he realize the enhancement of the method? In fact, you only need to add the content to be enhanced before and after the proxy object calls the method of the proxy object.

We can write our enhanced logic at any position before and after the cry method. Next, we will use two print outputs to simulate the enhanced method.

public class ProxyChick implements Animal{
    private String name;
    private Chick chick;

    public ProxyChick(String name) {
        this.name = name;
    }

    @Override
    public void cry() {
        if (chick==null){
            chick = new Chick(name);
        }
        //enhance before method
        System.out.println("a real eel");
        chick.cry();
        //enhance after method
        System.out.println("learn to sing and dance rap play basketball");
    }
}

2.3 Advantages and disadvantages of static proxy

  • advantage:
    • Using the proxy mode brings high scalability to the program
  • shortcoming:
    • In order to implement the proxy pattern, brings additional work
    • Since the proxy object needs to be passed before using the proxy object, it will increase the time overhead
    • Using static proxies requires programmers to write a large number of proxy objects and increase workload

3. Dynamic proxy

Core: No need to create a proxy object for the class you want to proxy in advance

Key points of code implementation: Proxy class and InvocationHandler interface provided under java.lang.reflect package

The following is a simple dynamic proxy implementation process

3.1 Simple code implementation of dynamic proxy

The first few steps are similar to the static proxy. First, create an interface and define the behavior

public interface Animal {
    void cry();
}

Create the implementation class of the interface, that is, the proxied class

public class Chick implements Animal{
    private String name;

    public Chick(String name) {
        this.name = name;
        birth(name);
    }

    private void birth(String name) {
        System.out.println("name is"+name+"the chicken was born");
    }

    @Override
    public void cry() {
        System.out.println("i am a barking"+name+"chicken");
    }
}

Next, is the specific implementation of the dynamic proxy, creating the AnimalInvocationHandler class, which implements the InvocationHandler interface

Dynamic proxy process analysis:

1.AnimalInvocationHandler holds a proxy object

2. The method executed by the proxy object will be replaced by the invoke method in AnimalInvocationHandler

3. The proxy object will execute the method of the proxy object and other code statements in the invoke method in the invoke method

The above three steps are actually the main principle of Spring Aop

public class AnimalInvocationHandler<T> implements InvocationHandler {
    //hold a proxied object
    private T target;

    public AnimalInvocationHandler(T target) {
        this.target = target;
    }

    /**
     * Three of the parameters
     * proxy: An object representing this dynamic proxy
     * method: the method being executed
     * args: Parameters passed in when calling the method
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("Proxy execution"+proxy.getClass().getName()+"Category"+method.getName()+"method");
        Object invoke = method.invoke(target, args);
        System.out.println("Agent execution ends~");
        return invoke;
    }
}

test

public class DynamicProxyTest {
    public static void main(String[] args) {
        //Create a proxy object
        Animal chick = new Chick("Cai Xukun");
        System.out.println("======================");
        //Create an InvocationHandler, which is associated with the proxy object
        InvocationHandler chickHandler = new AnimalInvocationHandler<Animal>(chick);
        //Get the proxy object, and every method executed by the proxy object will be replaced by the invoke method in the InvocationHandler just now
            Animal chickProxy = (Animal) Proxy.newProxyInstance(Animal.class.getClassLoader(),new Class<?>[]{Animal.class},chickHandler);

        chickProxy.cry();
    }
}

Analysis of the above code: First, the chick object is the object that needs to be proxied. We pass the chick to the chickHandler, and when creating the proxy object chickProxy, the chickHandler is also passed in as a parameter. Finally, the method in the proxy object chickProxy is executed When, they are replaced by the invoke method in chickHandler.

3.2 Characteristics of dynamic proxy

  • Unlike the static proxy, in the above code implementation, we did not see the specific proxy class. The proxied object and the proxy object in the dynamic proxy are proxyed through InvocationHandler, so there is no need to write one for each class. The proxy class only needs to be modified in the invoke method.

Tags: Java Design Pattern Proxy Pattern

Posted by bav on Fri, 13 Jan 2023 22:08:57 +0530