-->

Dynamic proxy for concrete classes

2019-02-06 00:47发布

问题:

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?

回答1:

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.



回答2:

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



回答3:

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.



回答4:

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.