Static agents and dynamic proxies

Source: Internet
Author: User
Proxy mode (static proxy)

The proxy mode is to provide a proxy for other objects to control access to this object.

The definition is also not good understanding, the previous "Big talk design pattern" diagram.

The Subject class (typically an abstract class or interface) defines a method.

The Realsubject class implements this interface, and in normal circumstances we only need to new the instance object of this class, and then call this method.

However, if we have a need to say that we want to do something before and after this method, the original method is not enough.

To rent a house to make an analogy:

Landlord Lee boss has a house, he intends to rent, but took people to see the house several times, found himself not so much time. So he entrusted the House to the intermediary company Xiao Wang, Xiao Wang help him to take people to look at the house, and then charge the intermediary fee.

In this case, the house is Lee's boss, he (Realsubject) will rent the house this authority entrusted to the small Wang (Proxy).

Abstract

First of all, abstract out the landlord this interface, and Lee boss is its concrete implementation.

public interface Landlord {    boolean rental();}
Specific objects

The landlord is an abstract concept, and Lee Boss, is a meaningful landlord, we call it an implementation of the landlord.

public class LandlordImpl implements Landlord {    public boolean rental() {        System.out.println("李老板的房子出租啦");        return true;    }}
Proxy Object

The proxy represents the functionality of the real object and adds access control on top of it.

That is the intermediary Xiao Wang, he won the authorization of the Boss Lee, can take people to see the house, but Lee boss clear their own conditions, rent at least 5000, if the beauty can consider a point (Xiao Wang on behalf of the boss Lee to do some filtering (access control)).

If the tenant is satisfied, want to rent a house and said to Xiao Wang. Of course, Xiao Wang wants to rent a tenant to the tenants, there is a commission. However, the specific house rent does not rent or to see the landlord.

We can define intermediary Xiao Wang is the landlord's proxy object. He represents rent-a-house and access control.

public class LandlordProxy implements Landlord{    private final Landlord landlord;    public LandlordProxy(Landlord landlord) {        this.landlord = landlord;    }    public boolean rental() {        beforeRental();        if (landlord.rental()) {            afterRental();        }        return false;    }    private void afterRental() {        System.out.println("收取佣金");    }    private void beforeRental() {        System.out.println("带人看房子");    }    }

If one day, boss Lee think a day to accept up to 5 times to see the room.

Obviously, it needs to be controlled by Xiao Wang. Then our class can change that.

public class LandlordProxy implements Landlord{    private final Landlord landlord;    private static final int NUM_ALLOWED = 5;    private int numPersons = 1;    public LandlordProxy(Landlord landlord) {        this.landlord = landlord;    }    public boolean rental() {        if (numPersons < NUM_ALLOWED) {            System.out.println("今天李老板不接客了");        } else {            beforeRental();            numPersons++;            if (landlord.rental()) {                afterRental();            }        }        return false;    }    private void afterRental() {        System.out.println("收取佣金");    }    private void beforeRental() {        System.out.println("带人看房子");    }}

The proxy object is characterized by

  1. And the proxy object implements the same interface;
  2. An example of a Proxied object is included internally;
Advantages
    1. Real objects can focus on their own business logic control;
    2. Non-business logic related parts, can be handled by the proxy class;
    3. Hides the real object, exposes only the proxy object to the external.
    4. Extensibility: Because the same interface is implemented, the proxy object does not need to change the logic of the Proxied object regardless of how it changes.
Use occasions
    1. Control access to real objects;
    2. implementation of log records;
    3. Number of visits to the statistics object;
    4. Wait a minute.
Some thinking

Inside the proxy object, when is the real object initialized and who generated the initialized object?

In the code and books I have read, there are several, I am also very confused, the following are some of my views

Not recommended
    1. Initializes the real object inside the proxy object constructor.
public LandlordProxy() {    landlord = new LandlordImpl();}
    1. Constructors do not change, when using methods
public boolean rental() {    if(landlord==null){        landlord = new LandlordImpl();     }    if (numPersons < NUM_ALLOWED) {        System.out.println("今天李老板不接客了");    } else {        beforeRental();        numPersons++;        if (landlord.rental()) {            afterRental();        }    }    return false;}

The above two ideas are in the proxy object to initialize the real object, I personally do not very much agree with this approach.

If we proxy agent is not only Lee boss, and Deputy King boss, then how to do? Want to write two basically identical proxy classes?

Recommended Practices

That's what we're using, passing in the constructor.

public LandlordProxy(Landlord landlord) {        this.landlord = landlord;}

The initialization of the real object is given to the caller.

In this way, no matter what the boss, they can manage their own rental methods, but the same work by the agent to do, and only need a proxy class. Implements the reuse of code.

Dynamic Agent

If there are one or two methods that need to be proxied, we use static proxies that are good.

But if there are 20 methods in our interface, each method needs to be preceded and followed by logic, such as logging the log. So, we always need to do some repetitive work, the same code needs to write many times, not only the time to write the pain, back maintenance is also very uncomfortable.

Based on this, the dynamic agent was born.

Dynamic creation of proxy classes using the reflection mechanism while the program is running

In Java, implementing dynamic proxies is simple

Define an implementation InvocationHandlerThe class

As shown below

public class DynamicProxy implements InvocationHandler {    private Object target;    public DynamicProxy(Object target) {        this.target = target;    }    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {        System.out.println(System.currentTimeMillis() + " 进入了方法");        // 中间是这个方法        Object result = method.invoke(target, args);        System.out.println(System.currentTimeMillis() + " 方法执行完毕");        return result;    }}

targetIs the real object that we need the proxy, which is recommended to be passed in the constructor.

To implement the invoke logic that we need within and around the method, in the middle is

Object result = method.invoke(target, args);

Finally, result you can return.

Calling a defined class
 public static void main(String[] args) {    Landlord landlord = new LandloadImpl();    DynamicProxy dynamicProxy = new DynamicProxy(landlord);    // 这一步是关键    Landlord landlordProxy = (Landlord) Proxy.newProxyInstance(            landlord.getClass().getClassLoader(),            landlord.getClass().getInterfaces(),            dynamicProxy    );    landlordProxy.rental();}

We're actually going to use the JDK to provide us with the function that returns the interface of the newProxyInstance corresponding proxy object, and we call the appropriate method.

Optimization

newProxyInstancemethod requires an incoming parameter to be further optimized.

We DynamicProxy can join the function in the method.

@SuppressWarnings("unchecked")public <T> T getProxy() {    return (T)Proxy.newProxyInstance(            target.getClass().getClassLoader(),            target.getClass().getInterfaces(),            this    );}

This is a lot easier when we get proxy objects, and main functions can be rewritten like this

public static void main(String[] args) {    Landlord landlord = new LandloadImpl();    DynamicProxy dynamicProxy = new DynamicProxy(landlord);    Landlord landlordProxy = dynamicProxy.getProxy();    landlordProxy.rental();}

The dynamic agent is convenient for us, but the dynamic proxy provided by the JDK, we can know through the newproxyinstance function that the object being proxied must implement an interface .

What if the object we want to proxy does not have an interface?

The following article intends to talk about how CGLIB and sping Aop are opening a new world for us.

The end of the acting story

Finally, intermediary Xiao Wang and Lee boss story of the outcome is how?

Programmer small H Rent a house, Lee boss and Xiao Wang according to the provisions of the intermediary fee 1750, the last small Wang, Lee boss and small H discussed a bit, do not walk the company's process, pay 1000 yuan on the good.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.