Explain to your girlfriend what the proxy mode is

foreword

Only the bald head can become stronger

Looking back at the front:

Multi-threading will come to an end. After writing multi-threading yesterday, I originally planned to read the knowledge points of IO. Later, I looked at several models of IO, and then read "Java Programming Ideas". I don't know where to start~

When I saw FilterInputStreamHehe , I saw the decoration modeFilterOutputStream that I often heard before (the students who have a certain understanding of IO may know the sentence: the decoration mode is the most used in IO)!

Seeing this, do you think I'm going to talk about the decoration mode? No, today we will talk about what the proxy mode is (it's just so skinny, let's talk about the decoration mode tomorrow~).

Inspired by Zhihu's @Beautiful Java article and "Zen of Design Patterns", I will also come up with a brain-opening article..

As you can see from the title, this article was written for my girlfriend. Ever since she found out that I opened an official account, she has read the articles I wrote every day. When she wrote some small algorithms before, she thought programming was quite interesting and wanted to learn it. However , since I started writing Java containers and multi-threading, she said she couldn't understand it at all. So, now to write something noble and easy to understand .


    GirlFriend girlFriend = new GirlFriend();
    sayingProxy(girlFriend);

Then let's start. If there are mistakes in the article, please bear with me and correct me in the comment area~

Disclaimer: This article uses JDK1.8

1. Introduction to the agent mode

The proxy pattern is a very well-understood design pattern. There are proxies everywhere in life :

  • As a star, Wang Baoqiang can't do everything by himself (about TV series, scheduling, etc.), so he hired an agent
  • What should I do if it is troublesome to go to the hospital for registration? Find a scalper to help us register
  • The technical level of King Glory is not enough, what should I do if I want to score higher? Please train the game
  • What should I do if I write some illegitimate code and get caught by the police? Ask a lawyer to help us with the lawsuit

Whether it is an agent, a scalper, a game booster, or a lawyer, they all have to help us . But they can't do it all by themselves, and just deal with the junk (things we don't want to do, or can't do) on a "me" basis.

  • The director asked Huang Baoqiang's agent to let Wang Baoqiang make a movie !
  • The scalpers go in line so we can get on the phone !
  • The top score of the game booster is my WeChat account !
  • Lawyers help me deal with legal issues. If the lawsuit fails, I will still sit in jail !

Another example:

  • Now I'm an internet celebrity with a lot of followers. Fans want me to write code for them to see every day, so I definitely can't write code every day, am I very busy.... So, I went to find an agent. This broker represents me. When a loyal fan wants me to write code, they should first find an agent and tell the agent that they want me to write code.
  • Ten years on, I'm getting redder and less hair . It wasn't that the fans wanted me to write code, I did. I will be charged. However, as a public figure, it is impossible for me to say: I will only write code if I have to receive 100 million. So this makes the agent say to the fans: Only 100 million, I will write code.
  • No matter what the outside world wants me to do, it has to go through my agent. My broker also considers charges, requests to shirk them.
  • The broker is the agent, and it is me who actually writes the code

Therefore, the proxy mode is: what the current object is unwilling to do, and what cannot be done is entrusted to other objects . I just need to do my duty well!

2. Describe the proxy mode with code (static proxy)

Here's an interface for programmers who write code every day

public interface Programmer {

    // 程序员每天都写代码
    void coding();

}

Java3y is also a programmer, he also writes code (the code written by each programmer is different, so it is divided into interface and implementation class)


public class Java3y implements Programmer {

    @Override
    public void coding() {
        System.out.println("Java3y最新文章:......给女朋友讲解什么是代理模式.......");
    }
}

At this time, Java3y is already an internet celebrity, and he doesn't want to write code boringly. He was thinking: "It's good to make money while writing code. When someone gives me money, I write code." However , Java3y's writing is too bad. Once there is any winter melon tofu, it will become a popular Internet celebrity in minutes. This is what Java3y does not want to see.

However, platforms such as Zhihu and Blog Park cannot give themselves the current object cannot do it )

So Java3y hired a **programmer V (agent)** to realize its plan. This programmer V will like, comment, and advocate for Java3y every time Java3y publishes an article. As long as there is traffic, the money is there.


public class ProgrammerBigV implements Programmer {
    
    // 指定程序员大V要让谁发文章(先发文章、后点赞)
    private Java3y java3y ;

    public ProgrammerBigV(Java3y java3y) {
        this.java3y = java3y;
    }

    // 程序员大V点赞评论收藏转发
    public void upvote() {
        System.out.println("程序员大V点赞评论收藏转发!");
    }

    @Override
    public void coding() {

        // 让Java3y发文章
        java3y.coding();

        // 程序员大V点赞评论收藏转发!
        upvote();
    }
}

The article (code) is still sent by Java3y, but the programmer V will like it every time it is sent.


public class Main {

    public static void main(String[] args) {

        // 想要发达的Java3y
        Java3y java3y = new Java3y();

        // 受委托程序员大V
        Programmer programmer = new ProgrammerBigV(java3y);

        // 受委托程序员大V让Java3y发文章,大V(自己)来点赞
        programmer.coding();
    }  
}

 

 

In this way, passers-by who do not know the truth think that Java3y is really powerful, and knowledge is paid.

2.1 Transparent proxy (normal proxy)

After a period of time, Java3y tasted the sweetness and felt that it was a way to make money. So Java3y gave the programmer big V enough money to let the programmer big V only do his business and not other people's business (broken other people's financial path).

Therefore, the programmer V only does the business of Java3y alone:


public class ProgrammerBigV implements Programmer {

    // 指定程序员大V要给Java3y点赞
    private Java3y java3y ;

    // 只做Java3y的生意了
    public ProgrammerBigV() {
        this.java3y = new Java3y();
    }

    // 程序员大V点赞评论收藏转发
    public void upvote() {
        System.out.println("程序员大V点赞评论收藏转发!");
    }

    @Override
    public void coding() {

        // 让Java3y发文章了
        java3y.coding();

        // 程序员大V点赞评论收藏转发!
        upvote();

    }
}

Therefore, when the programmer V wants to earn some pocket money, it is just fine to let Java3y publish articles.


public class Main {

    public static void main(String[] args) {

        // 受委托程序员大V
        Programmer programmer = new ProgrammerBigV();

        // 受委托程序员大V让Java3y发文章,大V来点赞
        programmer.coding();
        
    }
}

At this point, the real object (Java3y) is transparent to the outside world .

2.2 Proxy class custom method

The programmer V saw that Java3y has been smooth sailing and made a lot of money. I thought it was time to increase the price, so after I liked it, I told Java3y that each like would add 100 yuan !

So, programmer V added another method:addMoney()


public class ProgrammerBigV implements Programmer {


	// ..省略了上面的代码

    // 加价啦
    public void addMoney() {
        System.out.println("这次我要加100块");
    }

    @Override
    public void coding() {

        // 让Java3y发文章了
        java3y.coding();

        // 程序员大V点赞评论收藏转发!
        upvote();

        // 加价
        addMoney();

    }
}

So the programmer V can add 100 more each time:

 

 

3. Dynamic Agent

A few years have passed, and Java3y still hasn't made a fortune relying on programmers' big V likes (essentially, Java3y has no dry goods, and it has not been recognized by the public). At this time, many people have been promoted to programmer V, but the previous programmer V has been accumulating money... Although Java3y tasted the sweetness at the beginning, but now Java3y's finances are deficient.

Java3y believes that its failure: it must be the programmer V who turned the door for me to like it and was seen through, and the people who eat melons know it, and he charges so much.

So Java3y does not invite programmers to be big V, and invites the water army to like it (the water army is cheap, as long as you can like it):

public class Main {

    public static void main(String[] args1) {

        // Java3y请水军
        Java3y java3y = new Java3y();

        Programmer programmerWaterArmy = (Programmer) Proxy.newProxyInstance(java3y.getClass().getClassLoader(), java3y.getClass().getInterfaces(), (proxy, method, args) -> {

            // 如果是调用coding方法,那么水军就要点赞了
            if (method.getName().equals("coding")) {
                method.invoke(java3y, args);
                System.out.println("我是水军,我来点赞了!");

            } else {
                // 如果不是调用coding方法,那么调用原对象的方法
                return method.invoke(java3y, args);
            }

            return null;
        });

        // 每当Java3y写完文章,水军都会点赞
        programmerWaterArmy.coding();

    }

}

Whenever Java3y publishes an article, Shui Jun will like it.

 

 

Java3y sighs: It is really convenient to invite the navy ~

3.1 Dynamic proxy calling process

Let's take a look at how the navy was invited:

Java provides a Proxy class, which can generate a proxy object of an object by calling its newInstance method. This method requires three parameters:

 

write picture description here

 

  • Parameter 1: Which class loader is used to generate the proxy object [usually we use the loader of the proxied class]
  • Parameter 2: Generate the proxy object of which object, specify through the interface [specify the interface of the class to be proxied]
  • Parameter three: what to do in the method of the generated proxy object [implement the handler interface, we can implement it as we want]

Before writing dynamic proxies, a few concepts should be clarified:

  • The proxy object has the same methods as the target object [because the second parameter specifies the interface of the object, the proxy object will implement all the methods of the interface]
  • What method the user calls the proxy object is calling the invoke method of the processor. 【Intercepted】
  • The use of JDK dynamic proxy must have an interface [parameter two requires an interface]

As mentioned above: the proxy object will implement all the methods of the interface, and these implemented methods will be handled by our handler !

  • All methods implemented through dynamic proxies are all implemented by invoke()calling

 

 

So the dynamic proxy invocation process is like this:

 

 

3.2 The difference between static proxy and dynamic proxy

It is obvious that:

  • A static proxy needs to write its own proxy class --> the proxy class needs to implement the same interface as the target object
  • The dynamic proxy does not need to write its own proxy class ---> (it is dynamically generated)

When using a static proxy:

  • If the interface of the target object has many methods , then we still have to implement them one by one, which will be more troublesome

When using dynamic proxies:

  • The generation of the proxy object is to use the JDK API to dynamically build the proxy object in memory (requires us to specify the type of the interface implemented by the proxy object/target object), and implement all the methods of the interface by default .

4. Typical applications

When we wrote Chinese filters before, we needed to use the packaging design pattern to design a request class. If the Servlet does not provide us with the implementation class, it would be more troublesome for us to use the packaging design pattern

Now that we have learned about dynamic proxying, dynamic proxying is a skill that intercepts direct access to objects and can enhance objects

4.1 Chinese filter


    public void doFilter(final ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
        final HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) resp;

        response.setContentType("text/html;charset=UTF-8");
        request.setCharacterEncoding("UTF-8");


        //放出去的是代理对象
        chain.doFilter((ServletRequest) Proxy.newProxyInstance(CharacterEncodingFilter.class.getClassLoader(), request.getClass().getInterfaces(), new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

                //判断是不是getParameter方法
                if (!method.getName().equals("getParameter")) {

                    //不是就使用request调用
                   return method.invoke(request, args);
                }

                //判断是否是get类型的
                if (!request.getMethod().equalsIgnoreCase("get")) {
                   return method.invoke(request, args);
                }

                //执行到这里,只能是get类型的getParameter方法了。
                String value = (String) method.invoke(request, args);
                if (value == null) {
                    return null;
                }
                return new String(value.getBytes("ISO8859-1"), "UTF-8");
            }

        }), response);

    }

V. Summary

This is the first time to write an article in this way, the examples may be inappropriate, I hope you forgive me~

This article mainly explains several key points of the proxy mode, in fact, there are some details: such as "mandatory proxy" (the proxy object can only be found through the proxy object, and the proxy object cannot be directly accessed by bypassing the proxy object). It's just that it's used less, so I won't say it~~

To implement a dynamic proxy, there must be an interface. The dynamic proxy is based on the interface (all the methods of the interface are implemented). If there is no interface, we can consider the cglib proxy.

The cglib proxy is also called a subclass proxy, which builds a subclass from memory to extend the functionality of the target object !

I will not post the code here, because there are many proxy tutorials for cglib, which are similar to the dynamic proxy implementation~~~

In general: the proxy mode is a mode that we use a lot in writing code. The bottom layer of Spring's AOP is actually implemented by dynamic proxy --> Aspect-oriented programming. For details, please refer to the article I wrote earlier:

In fact, just remember one thing: the original object needs extra functionality, think about the technology of dynamic proxy !

References:

If there are any mistakes in the article, please correct me, and we can communicate with each other. Students who are used to reading technical articles on WeChat and want to get more Java resources can follow WeChat public account: Java3y . For everyone's convenience, I just created a new QQ group: 742919422 , you can also go to communicate. Thank you for your support! Hope to introduce more to other friends in need

Table of Contents Navigation for Articles :

 

 

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325646434&siteId=291194637