java static proxy and dynamic proxy

Posted by fiztec on Sat, 30 Oct 2021 10:38:02 +0200

1. Agency

The agent is in English P r o x y Proxy Proxy translated. The agents we have seen in life are probably the most common ones who sell mask in the circle of friends.

They take the goods from the manufacturer, publicize them in the circle of friends, and then sell them to acquaintances.

Reasonably speaking, customers can buy products directly from manufacturers, but in real life, there are few such sales models. Generally, the manufacturer entrusts the agent for sales, and the customer deals with the agent rather than directly associated with the actual producer of the product.

Therefore, the agent has a taste of middleman.

2. Agent mode

Agent pattern is a common design pattern in object-oriented programming.

This is a common UML diagram of a common agent pattern.

The following points should be noted:

  1. Users only care about interface functions, not who provides them. The interface in the figure above is Subject.
  2. The real implementer of the interface is RealSubject in the figure above, but it does not contact the user directly, but through an agent.
  3. Proxy is the proxy in the figure above. Because it implements the Subject interface, it can directly contact users.
  4. When the user calls Proxy, RealSubject is called inside the Proxy. Therefore, Proxy is a mediator, which can enhance RealSubject operation.

If it's difficult to understand, I'll illustrate it with examples. It is worth noting that agents can be divided into static agents and dynamic agents.

2.1 static agent

When we usually go to the cinema to see a film, do we often put advertisements at the beginning of the film?

The film is entrusted by the film company to the cinema for broadcasting, but the cinema can produce some economic benefits when playing the film, such as selling popcorn and coke, and then play some advertisements at the beginning and end of the film.

Now use the code to simulate.

(1) First of all, there must be an interface. The general interface is the basis for the implementation of proxy mode. This interface is named Movie, which represents the ability of Movie playback.

public interface Movie {
   void play();
 }

(2) Then, we need to have a real class that implements the Movie interface and a proxy class that only implements the interface.

public class RealMovie implements Movie {

    @Override
    public void play() {
        // TODO Auto-generated method stub
        System.out.println("You are watching the movie shawshank redemption");
    }
}

(3) This represents a real film. It implements the Movie interface. When the play() method is called, the Movie starts playing. What about Proxy proxy?

 public class Cinema implements Movie {

    RealMovie movie;

    public Cinema(RealMovie movie) {
        super();
         this.movie = movie;
     }
 
 
    @Override
     public void play() {
 
         guanggao(true);
 
         movie.play();
 
         guanggao(false);
     }
 
     public void guanggao(boolean isStart){
         if ( isStart ) {
             System.out.println("The movie starts right away. Popcorn, coke and gum 9.8 Discount, come and buy it!");
         } else {
             System.out.println("The movie is over soon. Popcorn, coke and gum 9.8 Discount, buy it and eat it at home!");
         }
     }
 }

(4) Cinema is a Proxy object that has a play() method. However, when the play() method is called, it does some related interest processing, that is, advertising. Now, let's write the test code.

public class ProxyTest {

    public static void main(String[] args) {

        RealMovie realmovie = new RealMovie();

        Movie movie = new Cinema(realmovie);

        movie.play();

    }

}

Then observe the results:

The movie starts right away. Popcorn, coke and gum are 9.8% off. Come and buy it!
You are watching the movie shawshank redemption
The movie is over soon. Popcorn, coke and gum are 9.8% off. Buy them and eat them at home!

Now we can see that the proxy mode can add and enhance some functions by extending the proxy class without modifying the proxy object. It is worth noting that the proxy class and the proxied class should jointly implement an interface or inherit a class.

The above describes the content of static proxy. Why is it called static? Because its type is predetermined, such as Cinema in the above code.

2.2 dynamic agent

Since it is an agent, its function and purpose are no different from that of a static agent. The only difference is the difference between dynamic and static.

So what is the dynamic representation of dynamic agents?

In the code in the previous section, Cinema class is an agent. We need to write code manually to make Cinema implement the Movie interface. In the dynamic agent, we can let the program automatically create an agent implementing the Movie interface in memory when running without defining Cinema class. This is why it is called dynamic.

Maybe the concept is more abstract. Now give an example to illustrate the situation.

Suppose there is a large shopping mall with many counters and one counter selling Maotai liquor. We simulate the code.

(1) SellWine is an interface. You can understand it as a license to sell wine. We also need a counter to sell wine.

public interface SellWine {

     void mainJiu();

}

(2) Then create a class Maotai Jiu. Yes, it means Maotai.

public class MaotaiJiu implements SellWine {

    @Override
    public void mainJiu() {
        // TODO Auto-generated method stub
        System.out.println("I sell Maotai.");

    }

}

(3) GuitaiA implements the InvocationHandler class. What does this class mean? Don't panic, I'll explain later.

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


public class GuitaiA implements InvocationHandler {

    private Object pingpai;


    public GuitaiA(Object pingpai) {
        this.pingpai = pingpai;
    }



    @Override
    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable {
        // TODO Auto-generated method stub
        System.out.println("The sales start counter is: "+this.getClass().getSimpleName());
        method.invoke(pingpai, args);
        System.out.println("End of sale");
        return null;
    }

}

(4) Then we can sell wine.

package com.frank.test;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;


public class Test {

    public static void main(String[] args) {
        // TODO Auto-generated method stub

        MaotaiJiu maotaijiu = new MaotaiJiu();


        InvocationHandler jingxiao1 = new GuitaiA(maotaijiu);


        SellWine dynamicProxy = (SellWine) Proxy.newProxyInstance(MaotaiJiu.class.getClassLoader(),
                MaotaiJiu.class.getInterfaces(), jingxiao1);

        dynamicProxy.mainJiu();

    }

}

Here, we come into contact with a new concept. It doesn't matter. Let's leave it alone and see the results first.

Sales start counter: GuitaiA
I sell Maotai.
End of sale

See, I didn't implement a proxy class for the SellWine interface like a static proxy, but it still implements the same functions in the end. The difference is the reason why the dynamic proxy discussed earlier is so-called "dynamic".

3. Dynamic agent syntax

Relax. Let's start with the grammar. The grammar is very simple.

Dynamic code involves a very important class Proxy. It is through the static method newProxyInstance of Proxy that the Proxy is dynamically created.

Proxy

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

The meaning of its three parameters is explained below.

  • Loader is naturally a class loader
  • interfaces code is the interface to proxy
  • h an InvocationHandler object
Beginners should be unfamiliar with InvocationHandler. I'll talk about it right away.

InvocationHandler

InvocationHandler is an interface. The official document explains that each agent instance has an InvocationHandler implementation class associated with it. If the agent's method is called, the agent will notify and forward it to the internal InvocationHandler implementation class for processing.

public interface InvocationHandler {

    public Object invoke(Object proxy, Method method, Object[] args)
        throws Throwable;
}

InvocationHandler is just an invoke() method, which determines how to handle the method calls passed by the agent.

  • Proxy proxy object
  • Method the method called by the proxy object
  • args parameter in method called

Because the Proxy dynamically generated by Proxy will call the InvocationHandler implementation class, InvocationHandler is the actual executor.

public class GuitaiA implements InvocationHandler {

    private Object pingpai;


    public GuitaiA(Object pingpai) {
        this.pingpai = pingpai;
    }



    @Override
    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable {
        // TODO Auto-generated method stub
        System.out.println("The sales start counter is: "+this.getClass().getSimpleName());
        method.invoke(pingpai, args);
        System.out.println("End of sale");
        return null;
    }

}

GuitaiA is actually the place where wine is sold.

Now, we increase the difficulty. We want to sell not only Maotai liquor, but also Wuliangye.

public class Wuliangye implements SellWine {

    @Override
    public void mainJiu() {
        // TODO Auto-generated method stub
        System.out.println("I sell Wuliangye.");

    }

}

The Wuliangye class also implements the SellWine interface, indicating that it also has a license to sell wine and also sells it on GuitaiA.

public class Test {

    public static void main(String[] args) {
        // TODO Auto-generated method stub

        MaotaiJiu maotaijiu = new MaotaiJiu();

        Wuliangye wu = new Wuliangye();

        InvocationHandler jingxiao1 = new GuitaiA(maotaijiu);
        InvocationHandler jingxiao2 = new GuitaiA(wu);

        SellWine dynamicProxy = (SellWine) Proxy.newProxyInstance(MaotaiJiu.class.getClassLoader(),
                MaotaiJiu.class.getInterfaces(), jingxiao1);
        SellWine dynamicProxy1 = (SellWine) Proxy.newProxyInstance(MaotaiJiu.class.getClassLoader(),
                MaotaiJiu.class.getInterfaces(), jingxiao2);

        dynamicProxy.mainJiu();

        dynamicProxy1.mainJiu();

    }

}

Let's look at the results:

Sales start counter: GuitaiA
I sell Maotai.
End of sale
Sales start counter: GuitaiA
I sell Wuliangye.
End of sale

4. Role of agency

Some students may ask that they have learned the knowledge of agents, but what is the use of them?

The main function is to enhance the function without modifying the source code of the proxy object.

This is often seen in AOP aspect oriented programming.

In the software industry, AOP is the abbreviation of Aspect Oriented Programming, which means: Aspect Oriented Programming, a technology to realize the unified maintenance of program functions through precompile and runtime dynamic agent. AOP is the continuation of OOP, a hot spot in software development, an important content in Spring framework, and a derivative paradigm of functional programming. AOP can isolate each part of business logic, reduce the coupling between each part of business logic, improve the reusability of program, and improve the efficiency of development.

major function
Logging, performance statistics, security control, transaction processing, exception handling, etc.

The above reference is Baidu Encyclopedia's explanation of AOP. As for how to log functions and performance statistics through agents, you can refer to the relevant source code of AOP and think about it carefully.

Like the notes, many students may wonder when I use an agent?

It depends on what you want to do. You've learned the grammar. The rest depends on the business requirements. It is suitable for the framework to realize logging function.

At this point, the static agent and dynamic agent are finished.

5. Summary

  1. Agents are divided into static agents and dynamic agents.
  2. Static proxy, the proxy class needs to write its own code.
  3. Dynamic proxy. The proxy class is generated through the Proxy.newInstance() method.
  4. Whether static agent or dynamic agent, agent and agent should implement two interfaces. Their essence is interface oriented programming.
  5. The difference between static Proxy and dynamic Proxy is whether the developer should define the Proxy class himself.
  6. Dynamic Proxy dynamically generates proxy class through Proxy, but it also specifies an implementation class of InvocationHandler.
  7. The purpose of proxy pattern is to enhance the function of existing code.

Reprinted from: https://www.cnblogs.com/cC-Zhou/p/9525638.html

Topics: Java Dynamic Proxy