Home > Java > javaTutorial > A brief introduction to InvocationHandler of Java dynamic proxy

A brief introduction to InvocationHandler of Java dynamic proxy

不言
Release: 2018-10-22 15:47:00
forward
2700 people have browsed it

This article brings you a brief introduction to InvocationHandler of Java dynamic proxy. It has certain reference value. Friends in need can refer to it. I hope it will be helpful to you.

There are very in-depth articles on the Internet about Java's dynamic proxy, Proxy and InvocationHandler concepts. In fact, these concepts are not that complicated. Now we understand what InvocationHandler is through the simplest example. It is worth mentioning that InvocationHandler is widely used in Spring framework implementation, which means that if we understand InvocationHandler thoroughly, we will lay a solid foundation for future Spring source code learning.

Develop an interface that contains two methods that can greet "hello" or "goodbye" to the specified person.

public interface IHello {
   void sayHello(String name);
   void sayGoogBye(String name);
}
Copy after login

Create a simple class to implement this IHello interface.

public class Helloimplements implements IHello {
    @Override
    public void sayHello(String name) {
        System.out.println("Hello " + name);
    }
    @Override
    public void sayGoogBye(String name) {
        System.out.println(name+" GoodBye!");
    }
}
Copy after login

Consuming this implementation class is nothing special so far.

Now suppose we receive this requirement: The boss requires that every time the implementation class greets someone, the details of the greeting must be recorded in a log file. For the sake of simplicity, we print the following line of statement before greeting to simulate the logging action.

System.out.println("问候之前的日志记录...");
Copy after login

You may say, this is not simple? Directly modify the corresponding method of Helloimplements and insert this line of log into the corresponding method.

A brief introduction to InvocationHandler of Java dynamic proxy

However, the boss’s request is that you are not allowed to modify the original Helloimplements class. In real scenarios, Helloimplements may be provided by a third-party jar package, and we have no way to modify the code.

A brief introduction to InvocationHandler of Java dynamic proxy

You may say that we can use the proxy pattern in the design pattern, that is, create a new Java class as a proxy class, and also implement IHello interface and then pass an instance of the Helloimplements class into the proxy class. Although we are required not to modify the code of Helloimplements, we can write the logging code in the proxy class. The complete code is as follows:

public class StaticProxy implements IHello {

  private IHello iHello;

  public void setImpl(IHello impl){

  this.iHello = impl;

}

@Override

public void sayHello(String name) {

    System.out.println("问候之前的日志记录...");

    iHello.sayHello(name);

}

@Override

public void sayGoogBye(String name) {

     System.out.println("问候之前的日志记录...");

     iHello.sayGoogBye(name);

}

static public void main(String[] arg) {

     Helloimplements hello = new Helloimplements();

     StaticProxy proxy = new StaticProxy();

     proxy.setImpl(hello);

     proxy.sayHello("Jerry");

  }

}
Copy after login

This approach can achieve the requirements:

A brief introduction to InvocationHandler of Java dynamic proxy

Let’s look at how to use InvocationHandler to achieve the same effect. .

InvocationHandler是一个JDK提供的标准接口。看下面的代码:
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class DynaProxyHello implements InvocationHandler {
    private Object delegate;
    public Object bind(Object delegate) {
        this.delegate = delegate;
        return Proxy.newProxyInstance(
        this.delegate.getClass().getClassLoader(), this.delegate
        .getClass().getInterfaces(), this);
    }
    public Object invoke(Object proxy, Method method, Object[] args)
    throws Throwable {
        Object result = null;
        try {
            System.out.println("问候之前的日志记录...");
            // JVM通过这条语句执行原来的方法(反射机制)
            result = method.invoke(this.delegate, args);
        }
        catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }
Copy after login

The bind method in the above code is very similar to the setImpl method of my previous proxy class StaticProxy, but the input parameter type of this bind method is more universal. The logging code is written in the method invoke.

See how to use it:

static public void main(String[] arg) {
    DynaProxyHello helloproxy = new DynaProxyHello();
    Helloimplements hello = new Helloimplements();
    IHello ihello = (IHello) helloproxy.bind(hello);
    ihello.sayHello("Jerry");
}
Copy after login

The execution effect is exactly the same as that of StaticProxy solution.

Let’s debug it first. When the bind method is executed, the method Proxy.newProxyInstance is called, and the instance of the Helloimplements class is passed in.

A brief introduction to InvocationHandler of Java dynamic proxy

We observe the ihello variable returned by the statement IHello ihello = (IHello) helloproxy.bind(hello) in the debugger. Although its static type is IHello, please note that when observing its actual type in the debugger, it is not an instance of Helloimplements, but one processed by the JVM, including the line of log we handwritten in the invoke method. Document the code. The ihello type is $Proxy0.

A brief introduction to InvocationHandler of Java dynamic proxy

When the sayHello method of this variable processed by the JVM is called, the JVM automatically transfers the call to DynaProxyHello.invoke:

A brief introduction to InvocationHandler of Java dynamic proxy

So, in the invoke method, our handwritten logging code is executed, and then the original sayHello code is executed through Java reflection.

Some friends may ask, your InvocationHandler seems more complicated than the static proxy StaticProxy? what is the benefit?

Assume that the boss's needs have changed again, and different logging strategies should be used in the methods of calling greetings and saying goodbye.

Let’s see how to use InvocationHandler to implement it elegantly:

A brief introduction to InvocationHandler of Java dynamic proxy

I hope this example can give everyone an understanding of Java’s dynamic proxy InvocationHandler. Get the most basic understanding.

The above is the detailed content of A brief introduction to InvocationHandler of Java dynamic proxy. For more information, please follow other related articles on the PHP Chinese website!

Related labels:
source:segmentfault.com
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template