简体   繁体   中英

java.lang.reflect.Proxy and java.lang.reflect.InvocationHandler

What is the purpose of java.lang.reflect.Proxy and java.lang.reflect.InvocationHandler? when we need to create and use these on our application?

Proxy is a design pattern. We create and use proxy objects when we want to add or modify some functionality of an already existing class. The proxy object is used instead of the original one. Usually, the proxy objects have the same methods as the original one and in Java proxy classes usually extend the original class. The proxy has a handle to the original object and can call the method on that.

This way proxy classes can implement many things in a convenient way:

  1. logging when a method starts and stops
  2. perform extra checks on arguments
  3. mocking the behavior of the original class
  4. access to costly resources

Without modifying the original code of the class. (The above list is not extensive, it only list some examples).

To create an actual dynamic proxy class, all you need to do is implement the java.lang.reflect.InvocationHandler interface:

public Class MyDynamicProxyClass implements
java.lang.reflect.InvocationHandler
{
  Object obj;
  public MyDynamicProxyClass(Object obj)
  { this.obj = obj; }
  public Object invoke(Object proxy, Method m, Object[] args) throws
Throwable
  {
    try {
      // do something
    } catch (InvocationTargetException e) {
      throw e.getTargetException();
    } catch (Exception e) {
      throw e;
    }
    // return something
  }
}

That's all there is to it!Okay, well, you also have to have your actual proxy interface:

public interface MyProxyInterface
{
  public Object MyMethod();
}

Then to actually use that dynamic proxy, the code looks like this:

MyProxyInterface foo = (MyProxyInterface)
java.lang.reflect.Proxy.newProxyInstance(obj.getClass().getClassLoader(),
                                         Class[] { MyProxyInterface.class },
                                         new MyDynamicProxyClass(obj));

Knowing that the above code is just horribly ugly, I'd like to hide it in some type of factory method. So instead of having that messy code in the client code, I'll add that method to my MyDynamicProxyClass:

static public Object newInstance(Object obj, Class[] interfaces)
{
  return
java.lang.reflect.Proxy.newProxyInstance(obj.getClass().getClassLoader(),
                                                  interfaces,
                                                  new
MyDynamicProxyClass(obj));
}
That allows me to use the following client code instead:

MyProxyInterface foo = (MyProxyInterface)
  MyDynamicProxyClass.newInstance(obj, new Class[]
{ MyProxyInterface.class });

That is much cleaner code. It might be a good idea in the future to have a factory class that completely hides the entire code from the client, so that the client code looks more like:

MyProxyInterface foo = Builder.newProxyInterface();

Overall, implementing a dynamic proxy is fairly simple.

Ref :

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM