This is the 25th day of my participation in Gwen Challenge


👉 Design mode directory

First, what is the agency model

Take a look at Baidu’s explanation

Definition of proxy pattern: Provides a proxy for other objects to control access to that object. In some cases, an object is inappropriate or cannot directly reference another object, and a proxy object can act as an intermediary between the client and the target object. — Baidu Encyclopedia

I feel that this is too abstract, but there is a concept – “mediation”, the word embodies the essence of proxy mode, all proxy mode is actually a mediation, allowing users to use objects that are not convenient to use directly, without the need to consider the complicated process.

Advantages and disadvantages of using the proxy model

1. The advantages

  • It makes the responsibility of the code clearer, and after the broker, you don’t need to think beyond the business logic when using methods
  • It has high scalability and can be well combined with other methods
  • A proxy object can act as an intermediary between the client and the target object, thus acting as a mediator and protecting the target object

2. The shortcomings

  • This increases system complexity, which is inevitable, as the proxy pattern adds additional functionality without compromising usage
  • Some types of proxy patterns may slow down the processing of requests due to the addition of proxy objects between the client and the real object. (Personally, instances should be called to each other quickly and the efficiency should be about the same with or without proxies.)

The principle of 3.

“+” for compliance, “-” for non-compliance or irrelevant

The principle of Open the closed Single responsibility Di milt Replacement on the Richter scale Dependency inversion Interface segregation Synthesis of reuse
+ + +

Classification of agency mode

I categorize it here not by implementation but by the nature of the proxy pattern.

1. Enhanced agency

  1. The characteristics of

Core functionality remains the same (do not modify the original function) business independence (not modify the core business logic, reduce the complexity of system) used in the same Additional new features (just need additional does not affect the function of the agent of the original function of the function, is equivalent to add a buff) universality (enhancement function can be added to the other method)

In general, the enhanced agent only performs non-business operations on a method, such as security checks, locking, logging and other non-business operations.

  1. Common examples

Implementations of enhanced proxies can have static or dynamic proxies common examples are:

  • Spring AOP, declarative things
  • Monitor the operation (make a record after the user has done it)

2. Linked proxy

  1. The characteristics of

Similar to enhanced agents, core functions remain unchanged and business independence is more convenient to use

In general, linked proxies simplify the way we call methods, don’t change the business, and generally don’t do enhanced operations.

  1. Common examples

Linked proxy implementations can also be static or dynamic. Common examples are:

  • Mapper agent for MyBtis
  • Ribbon, Zuul, etc

Realization of agent mode

1. Static proxy

Static agent is the way of using manual writing code to do this, the target function can be changed without premise, realize the function expansion, extend the diversification, but the expansion of the need to write a lot of methods, increase management cost You first need to create an interface, the interface is defined in the proxy class and proxy classes in order to realize the method, and then create the proxy class and proxy class

/ * * *@authorXXJ * Static proxy test */
public class StaticProxy {
    public static void main(String[] args) {
        Company company=new Company("Real Estate Company"."Villa by the Sea");
        CompanyProxy companyProxy=new CompanyProxy(company,"Zhang");

        companyProxy.sale();
    }

    /** * interface */
    public interface Salor{
        public void sale(a);
    }

    /** * The agent class * the company that needs the agent */
    public static class   Company implements Salor{
        String name;
        String product;
        public Company(String name,String product){
            this.name=name;
            this.product=product;
        }
        @Override
        public void sale(a) {
            System.out.println(name+"Sell"+product); }}/** * Proxy class * intermediary */
    public static class CompanyProxy implements Salor{
        private Company company;
        private String worker;
        / * * *@paramCompany need to represent the company */
        public CompanyProxy(Company company,String worker){
            this.company=company;
            this.worker=worker;
        }
        @Override
        public void sale(a) {
            System.out.println(worker+"Sell -- contact customers --");
            System.out.println("Contact"+company.name+"Make a deal --");
            company.sale();
            System.out.println(worker+"Take the commission --"); }}}Copy the code

Personally, this is more like a linked proxy, because CompanyProxy does something in the sale method (if printing to the console is considered an operation), whereas CompanyProxy does something to print status information or monitor rather than company.sale().

2. Dynamic proxy

Proxy classes generated by dynamic proxies are generated by dynamic concatenation of bytecode and do not actually exist, whereas proxy classes do exist in static proxies

JDK dynamic proxy

JDK dynamic proxy does not need to manually extend the function of the method, but by a class to implement the InvocationHandler interface to unified management, do not have to write each method extension, so that the agent class management cost is reduced, but it will be troublesome to create the agent class, which can set a factory mode to create the agent class

Create a mediation class that implements the InvocationHandler interface. Then call the static newProxyInstance method provided by the Proxy to create the Proxy class.

/ * * *@authorXXJ * JDK dynamic proxy */
public class DynamicProxy {
    public static void main(String[] args) {
        Company company=new Company("Real Estate Company"."Villa by the mountain.");
        // Intermediary company
        CompanyHandler companyHandler=new CompanyHandler(company,"Anything sells the company.");
        // The class loader can be interpreted as a sales team leader who gets people to do the work
        ClassLoader classLoader=company.getClass().getClassLoader();
        // Ask Joe to work for a company that can sell anything
        Salor zhangsan= (Salor) Proxy.newProxyInstance(classLoader,
                company.getClass().getInterfaces(),companyHandler);
        zhangsan.sale();
    }

    /** * The handle class is equivalent to an intermediary company */
    public static class CompanyHandler implements InvocationHandler{
        private Company company;
        private String agentCompany;
        public CompanyHandler(Company company,String agentCompany){
            this.company=company;
            this.agentCompany=agentCompany;
        }
        / * * *@param* does not seem to work with proxy@paramMethod Calls the Method information of invoke *@paramParameter information of args method *@return
         * @throws Throwable
         */
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            System.out.println(agentCompany+"Sell -- contact customers --");
            System.out.println("Contact"+company.name+"Make a deal --");
            // Execute company's methods
            method.invoke(company,args);
            System.out.println(agentCompany+"Take the commission --");
            return null; }}/** * The agent class * the company that needs the agent */
    public static class  Company implements Salor {
        String name;
        String product;
        public Company(String name,String product){
            this.name=name;
            this.product=product;
        }
        @Override
        public void sale(a) {
            System.out.println(name+"Sell"+product); }}/** * interface */
    public interface Salor{
        public void sale(a); }}Copy the code

Cglib dynamic proxy

Cglib dynamic proxy is much easier to use than JDK dynamic proxy. You only need to write a ProxyFactory class to proxy other classes, and there is no need to write the interface. However, the process of generating the proxy class is complicated, and also depends on the third-party JAR package. You need to import spring’s Spring-Corejar package, write a proxy factory class, implement the MethodInterceptor interface, and provide methods to build the proxy class internally. You can generate the proxy class directly by putting it into the proxy factory class

maven

<dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-core</artifactId>
      <version>3.28..RELEASE</version>
    </dependency>
Copy the code
/ * * *@authorXXJ * Cglib dynamic proxy */
public class CglibDynamicProxy {

    public static void main(String[] args) {
        Company company=new Company("Real Estate Company"."Private Estate.");
        Company proxy= (Company) new ProxyFactory(company,"Sure to sell the company.").getProxyInstance();
        proxy.sale();
    }
    public static class ProxyFactory implements MethodInterceptor {
        private Company company;
        private String agentCompany;
        public ProxyFactory(a){}
        public ProxyFactory(Company company, String agentCompany){
            this.company=company;
            this.agentCompany=agentCompany;
        }

        // Create a proxy object for the target object
        public Object getProxyInstance(a){
            / / 1. Utility class
            Enhancer en = new Enhancer();
            //2. Set the parent class
            en.setSuperclass(company.getClass());
            // set the callback function
            en.setCallback(this);
            //4. Create subclasses (proxy object)
            return en.create();
        }
        @Override
        public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
            System.out.println(agentCompany+"Sell -- contact customers --");
            System.out.println("Contact"+company.name+"Make a deal --");
            // Execute company's methods
            method.invoke(company,objects);
            System.out.println(agentCompany+"Take the commission --");
            return null; }}/** * The agent class * the company that needs the agent */
    public static class   Company  {
        String name;
        String product;
        public Company(a){}
        public Company(String name,String product){
            this.name=name;
            this.product=product;
        }
        public void sale(a) {
            System.out.println(name+"Sell"+product); }}}Copy the code

Five, the summary

No matter what kind of proxy mode needs to meet the two characteristics of not changing core functions and business logic, once violated, it will greatly increase the complexity of the system.

To end this chapter, I’ll give you two examples from my life. Enhanced agents, like microwaves (proxies), when we need to heat food (proxies), we put it in the microwave, and then we get a heated food (with new features). This process doesn’t change the nature of food (doesn’t change the core function), we can still eat it (if it’s too hot to eat, you can eat it) (same usage) everything can be heated (universality) and you can heat anything else if you want to. There are too many examples of linked agents, like delivery, where we just need to place a mobile order to buy a hamburger (easier to use) and all we end up doing with a mobile order is buying a hamburger (without changing the core function).

— — — — — — — — — — — — — — —

The more you know, the more you don’t know.

If you have any questions about the content of this article, please comment directly or email me. If you think my writing is good, a “like” is also a sign of support

Shall not be reproduced without permission!