17

I want to define a method interceptor in a Java program in other words I want to have a behaviour which is executed at each method call. This application isn't executed in an application server and therefore I can't use the EJB around invoke interceptors. I have found a nice Proxy API in the standard Java libraries but its limited because it needs an interface in the proxy creation:

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

Is there a similar API which doesn't force Foo.class to be declared as an interface?

dma_k
  • 10,431
  • 16
  • 76
  • 128
eliocs
  • 18,511
  • 7
  • 40
  • 52

4 Answers4

6

Why not use CGLIB ? See this article for more information.

What if you want to proxy legacy classes that do not have interfaces? You can use CGLIB. CGLIB is a powerful, high-performance code generation library. Under the cover, it uses ASM, a small but fast bytecode manipulation framework, to transform existing byte code to generate new classes. CGLIB is faster than the JDK dynamic proxy approach. Essentially, it dynamically generates a subclass to override the non-final methods of the proxied class and wires up hooks that call back to the user-defined interceptors.

Brian Agnew
  • 268,207
  • 37
  • 334
  • 440
  • I am new to CGLIB. My understanding is it generates class binary in memory, but the existing class loader just loads class from file system, so how it uses its own classloader? – Chao Aug 02 '16 at 07:31
1

Unfortunately there is no such API for classes. Many frameworks are using bytecode generation libraries like CGLIB to achieve this.

Tomasz Nurkiewicz
  • 334,321
  • 69
  • 703
  • 674
1

You can try one of the mocking classes. The simplest approach may be to sub-class, your class. Or you could use AOP to inject the logging code you want.

Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
0

sun.misc.ProxyGenerator can be used to generate proxy classes and doesn't check that their "interfaces" are all interfaces. Its generateClassFile method gives you the bytecode as a byte array, which you can save to link into future builds or alter with third-party tools.

Note that if any of the "interfaces" has a final method, you'll get an error when you try to load the class.