There are two proxy modes, including static proxy mode and dynamic proxy mode, according to the creation period of proxy objects

  • Static proxies are generated by developers or specific tools that automatically generate source code and then compile it before the program runs.
  • Dynamic proxies are created dynamically while the program is running, using Java’s reflection mechanism.

The proxy pattern has several characteristics:

  • Proxied and proxied classes implement the same interface
  • The proxy class itself does not really implement the service
  • A proxy class is associated with a proxied class. A proxied class object is associated with a proxied class object
  • The proxy class mainly preprocesses messages for the proxied class, filters messages, processes messages, and so on

Static proxy mode

In this class, I have to take part in the running test. I have to take part in the running test.

public interface IRunner {
    void run(a);
}
Copy the code
public class Runner implements IRunner{
    @Override
    public void run(a) {
        // As a student taking the running test, your only task is to run and nothing else should be concerned
        System.out.println("Running");
        try {
            // Run for 5 seconds
            sleep(5000);
        } catch(InterruptedException e) { e.printStackTrace(); }}}Copy the code

Well, at this point, the students have understood their task. But you have to get grades on exams, so how do you get grades? Is it for the students to take notes themselves? Of course not, at this point, a key person will appear “physical education teacher”, the physical education teacher will hold a stopwatch for us to record the time. So, a teacher:

public class Teacher implements IRunner{
    IRunner runner;

    public Teacher(IRunner _runner) {
        this.runner = _runner;
    }

    @Override
    public void run(a) {
        long start = System.currentTimeMillis();
        System.out.println("The teacher holds a stopwatch in place of the students -> Run to start the time :"+ start);
        runner.run();
        long end = System.currentTimeMillis();
        System.out.println("The teacher holds a stopwatch in place of the students -> The end of the run :"+end);
        System.out.println("Time:"+ ((int)(end - start)/1000) +"Seconds"); }}Copy the code

Ok, now that the teachers and students are ready, the running test begins

public class Client {
    public static void main(String[] args) {
        IRunner proxy = new Teacher(newRunner()); proxy.run(); }}Copy the code

Results:The whole process above has used the static agent mode, the role of the teacher is the agent, he is the time for the student agent, and the students only need to take care of their own business, run well. The proxy class of the proxy mode is mainly to add some functions unrelated to the proxy object. Just like the example above, students just run the test, and the timing is left to the teacher.

Dynamic proxy mode

Static proxy mode is not suitable for multiple classes that need to be propped up. After all, each class needs to be propped up with a corresponding proxy, resulting in a large number of proxy classes. Also, to implement static proxies, you need to know exactly who the real object is, or you’ll be confused. So this is where the dynamic proxy model comes in. When using dynamic proxies, we need to use the InvocationHandler interface and Proxy class provided by the JDK

Using the example above, rewrite it to the dynamic proxy pattern

Let’s start by implementing an InvocationHandler interface:

public class ProxyHandler implements InvocationHandler {

    private Object object;

    public ProxyHandler(Object _object) {
        this.object = _object;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        long start = System.currentTimeMillis();
        System.out.println("The teacher holds a stopwatch in place of the students -> Run to start the time :"+ start);
        method.invoke(object,args);
        long end = System.currentTimeMillis();
        System.out.println("The teacher holds a stopwatch in place of the students -> The end of the run :"+end);
        System.out.println("Time:"+ ((int)(end - start)/1000) +"Seconds");
        return null; }}Copy the code

This is then modified at the invocation place to dynamically generate the Proxy class through the Proxy

public class Client {
    public static void main(String[] args) {
        // Static proxy mode call
        /* IRunner proxy = new Teacher(new Runner()); proxy.run(); * /

        // Dynamic proxy mode call
        IRunner runner = new Runner();
        ProxyHandler handler = new ProxyHandler(runner);
        // Generate the proxyIRunner proxy = (IRunner) Proxy.newProxyInstance(runner.getClass().getClassLoader(), runner.getClass().getInterfaces(),handler); proxy.run(); }}Copy the code

Running results:

At this point, the Teacher class in the original static proxy class is no longer useful, because this is a proxy object that is required in static proxy mode. In dynamic proxy mode, the JDK has been assigned to generate the proxy class.

additional

In addition to static proxy, dynamic proxy, there are mandatory proxy, transparent proxy and so on a series of writing methods to adapt to different scenarios, can be found on the Internet corresponding information. Or I will add it to this article sometime later.

The last

If there is any wrong please correct, let me learn a wave, promote each other, learn from each other!!