Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I intercept a method invocation with standard java features (no AspectJ etc)?

Tags:

I want to intercept all method invocations to some class MyClass to be able to react on some setter-invocations.

I tried to use dynamic proxies, but as far as I know, this only works for classes implementing some interface. But MyClass does not have such an interface.

Is there any other way, besides implementing a wrapper class, that delegates all invocations to a member, which is an instance of the MyClass or besided using AOP?

like image 896
Tobias Hilka Avatar asked Feb 23 '09 08:02

Tobias Hilka


People also ask

Which is the preferred way to intercept Java calls?

Defining Interceptors The preferred way to define in Java code is by using meta-data annotations. They can be defined in the application descriptor as well, but, in that case they are not portable across Java EE servers. Some of the meta-data annotations found in the javax.

What is interceptor in Java with example?

Interceptors are used in conjunction with Java EE managed classes to allow developers to invoke interceptor methods on an associated target class, in conjunction with method invocations or lifecycle events. Common uses of interceptors are logging, auditing, and profiling.

What is method invocation statement in Java?

The method invocation statement calls a method defined for the class of a reference variable. This statement is used for methods of user classes, system classes, and external classes. You can invoke any method defined for the class of the reference variable or any inherited method from the variable's superclasses.

What does method invoke return?

invoke() method returns the object which is returned after that method execution!


2 Answers

As you note, you cannot use JDK dynamic proxies (no interface), but using Spring and CGLIB (JAR included with Spring), you can do the following:

public class Foo {     public void setBar()     {         throw new UnsupportedOperationException("should not go here");     }      public void redirected()     {         System.out.println("Yiha");     } }  Foo foo = new Foo(); ProxyFactory pf = new ProxyFactory(foo);  pf.addAdvice(new MethodInterceptor() {     public Object invoke(MethodInvocation mi) throws Throwable     {         if (mi.getMethod().getName().startsWith("set"))         {             Method redirect = mi.getThis().getClass().getMethod("redirected");             redirect.invoke(mi.getThis());         }         return null;     } });  Foo proxy = (Foo) pf.getProxy(); proxy.setBar(); // prints "Yiha" 
like image 53
eljenso Avatar answered Sep 20 '22 22:09

eljenso


If you are prepared to do something really ugly, have a look at:

http://docs.oracle.com/javase/7/docs/technotes/guides/jpda/

Basically the debugger interface ought to allow you to attach like a debugger, and hence intercept calls. Bear in mind I think this is a really bad idea, but you asked if it was possible.

like image 43
Nick Fortescue Avatar answered Sep 20 '22 22:09

Nick Fortescue