Java Dynamic proxy)

Source: Internet
Author: User

The following content is translated from an unknown document:

Overview

As intermediary between client and target, proxy is very useful in many cases.

To further understand the role of dynamic proxy, we first look at an instance that does not use the proxy mechanism.

Example of vehicle without proxy

public interface IVehicle {public void start();public void stop();public String getName();}
public class Car implements IVehicle {String name;public Car(String name) {this.name = name;}public void start() {System.out.println("start(): The car" + name + " started");}public void stop() {System.out.println("stop(): The car" + name + " stopped");}public String getName() {return this.name;}}
public class Client {public static void main(String[] args) {IVehicle v = new Car("BMW");v.start();v.stop();}}

The running result is

start(): The carBMW startedstop(): The carBMW stopped

The call relationship diagram in this example is

Example of vehicle using proxy

Remember: The main purpose of using a proxy is to better control access to the target, rather than enhancing the function of the target (functionality ).

The proxy controls the access to the target in the following ways:

  • Synchronization
  • Authentication
  • Remote Access
  • Lazy instantiation

public class VehicleProxy implements IVehicle {private IVehicle v;public VehicleProxy(IVehicle v) {this.v = v;}public void start() {System.out.println("VehicleProxy.start()");v.start();}public void stop() {System.out.println("VehicleProxy.stop()");v.stop();}public String getName() {System.out.println("VehicleProxy.getName()");return v.getName();}}
public class Client2 {public static void main(String[] args) {IVehicle car = new Car("BMW");IVehicle v = new VehicleProxy(car); v.start();v.stop();}}

The running result is

VehicleProxy.start()start(): The carBMW startedVehicleProxy.stop()stop(): The carBMW stopped

In this example, the call relationship is:

The above example of using a proxy seems to achieve our goal. Now, we want to print some log information before and after calling every method of car, for example, input parameters and output results. However, we also need to consider the following facts:

  • The car class and ivehicle interfaces are the code at the core business layer and cannot be easily modified;
  • A large number of codes have been used in the car class and ivehicle interfaces, so they cannot be greatly changed;
  • There may be many methods in the car class and ivehicle, and we hope to increase the call logs for each method at the minimum cost.
  • When we add new methods for the car class and ivehicle interfaces in the future, we hope that the call logs will be automatically added when these new methods are called.

Okay, it's time to look at the dynamic proxy.

Java Dynamic proxy

What is Java Dynamic proxy?

  • WhenDynamic proxy(Dynamic proxy class) After being created, it will implement a series of interfaces specified at runtime.
  • Proxy Interface(Proxy InterfaceIs an interface implemented by the proxy class.
  • Proxy instance(Proxy instanceIs an instance of the proxy class.
  • Each proxy instance is associatedInvocation handler object(ImplementedInvocationhandlerInterface)
  • If a method on the proxy instance is called through the proxy interface, the method call will be forwarded (dispatch) to the invocation method associated with the proxy instance

Java. Lang. Reflect. proxy class

The proxy class provides static methods for creating dynamic proxy classes and dynamic proxy instances. It is also the parent class of dynamic proxy classes created by these static methods.

Create a dynamic proxy class for the interface FOO:

InvocationHandler handler = new MyInvocationHandler(...);Class proxyClass = Proxy.getProxyClass(Foo.class.getClassLoader(), new class[]{foo.class});Foo foo = proxyClass.getConstructor(new class[]{InvocationHandler.class}).newInstance(new Object[]{handler});

You can also create a dynamic proxy class for the interface Foo in the following ways:

InvocationHandler handler = new MyInvocationHandler(...);Foo foo = Proxy.newProxyInstance(Foo.class.getClassLoader(), new Class[]{Foo.class}, handler);

Dynamic proxy instance

We will transform the previous example using dynamic proxy as follows:

public interface IVehicle {public void start();public void stop();public String getName();}
public class Car implements IVehicle {String name;public Car(String name) {this.name = name;}@Overridepublic void start() {System.out.println("start(): The car " + name + " started");}@Overridepublic void stop() {System.out.println("stop(): The car " + name + " stopped");}@Overridepublic String getName() {System.out.println("getName(): The car " + name + "'s name is retrieved");return this.name;}}
import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.util.Arrays;public class VehicleHandler implements InvocationHandler {private IVehicle target;public VehicleHandler(IVehicle target) { this.target = target;}@Overridepublic Object invoke(Object proxy, Method m, Object[] args) throws Throwable {System.out.println("[Before Method Call]  The method " + m.getName() + "() begins with " + Arrays.toString(args));Object result =  m.invoke(target, args);System.out.println("[After Method Call]  The method " + m.getName() + "() ends with " + result);return result;}}
import java.lang.reflect.Proxy;public class Client {public static void main(String[] args) {IVehicle car = new Car("Ford");IVehicle proxiedCar = (IVehicle) Proxy.newProxyInstance(car.getClass().getClassLoader(), car.getClass().getInterfaces(), new VehicleHandler(car));proxiedCar.start();System.out.println("-------------------------------------------");String name = proxiedCar.getName();}}

The running result is

[Before Method Call]  The method start() begins with nullstart(): The car Ford started[After Method Call]  The method start() ends with null-------------------------------------------[Before Method Call]  The method getName() begins with nullgetName(): The car Ford's name is retrieved[After Method Call]  The method getName() ends with Ford

Related Article

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.