Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Decorating with java.lang.reflect.Proxy

...

Code Block
before util.CalcImpl.ctor()
after  util.CalcImpl.ctor()
Duration: 0 ms
before util.CalcImpl.add(java.lang.Integer, java.lang.Integer)
after  util.CalcImpl.add(java.lang.Integer, java.lang.Integer)
Duration: 16 ms

Decorating with java.lang.reflect.Proxy

If you are trying to decorate an object (i.e. just a particular instance of the class, not the class generally), then you can use Java's java.lang.reflect.Proxy. Groovy makes working with this easier than just Java. Below is a code sample taken out of a grails project that wraps a java.sql.Connection so that it's close method is a no-op:

Code Block

   protected Sql getGroovySql() {
      final Connection con = session.connection()
      def invoker = { object, method, args ->
         if (method.name == "close") {
            log.debug("ignoring call to Connection.close() for use by groovy.sql.Sql")
         } else {
            log.trace("delegating $method")
            return con.invokeMethod(method.name,args)
         }
      } as InvocationHandler;
      def proxy = Proxy.newProxyInstance( getClass().getClassLoader(), [Connection] as Class[], invoker )
      return new Sql(proxy)
   } 

If there were many methods to intercept, then this approach could be modified to look up closure in a map by method name and invoke it.

Decorating with Spring

The Spring Framework allows decorators to be applied with interceptors (you may have heard the terms advice or aspect). You can leverage this mechanism from Groovy as well.

...