简体   繁体   中英

How to intercept a method in java

Here is the method:

public static boolean startModule(Module mod, ServletContext servletContext, boolean delayContextRefresh)

Here is the method call in a java file:

WebModuleUtil.startModule(module, getServletContext(), false);

I cannot make any changes to these files, but I want to intercept the method and add some of my code (I want access to the parameters as well)

Code I wrote in another java file but not successful:

public void main(String[] args) throws Exception {

    Module module = null;
    WebModuleUtil wmb = new WebModuleUtil();
    ProxyFactory pf = new ProxyFactory(wmb);
    pf.addAdvice(new MethodInterceptor() {

        public Object invoke(MethodInvocation invocation) throws Throwable {
            if (invocation.getMethod().getName().startsWith("start")) {
                System.out.println("method " + invocation.getMethod() + " is called on " + invocation.getThis()
                        + " with args " + invocation.getArguments());
                System.out.println("********************");
                Object ret = invocation.proceed();
                System.out.println("method " + invocation.getMethod() + " returns " + ret);
                return ret;
            }
            return null;
        }
    });

    WebModuleUtil proxy = (WebModuleUtil) pf.getProxy();
    proxy.startModule(module, getServletContext(), false);      
}

private static ServletContext getServletContext() {
    // TODO Auto-generated method stub
    return null;
}

Use aop programming. For example try to read something about AspectJ.

Ex code:

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Service;

@Aspect
@Service
public class AspectDemo {

@Around("aop1()" ) 
public Object intercept(ProceedingJoinPoint joinPoint) throws Throwable {
   for (Object obj : joinPoint.getArgs()) {
      LOG.debug(obj);
   }
}

@Pointcut("execution(*my.example.packcage.startModule.*(..))")
  public void aop1() {
}

Aspect Oriented Programming (AOP) is made for this purpose, you can use AspectJ :

AspectJ enables clean modularization of crosscutting concerns, such as error checking and handling, synchronization, context-sensitive behavior, performance optimizations, monitoring and logging, debugging support, and multi-object protocols.

Or as you are using Spring you can use Spring 2.0 AOP :

Spring 2.0 introduces a simpler and more powerful way of writing custom aspects using either a schema-based approach or the @AspectJ annotation style. Both of these styles offer fully typed advice and use of the AspectJ pointcut language, while still using Spring AOP for weaving.

This is how to declare an Aspect:

@Aspect
public class NotVeryUsefulAspect {

}

And this is how to declare a pointCut:

@Pointcut("execution(* transfer(..))")// the pointcut expression
private void anyOldTransfer() {}// the pointcut signature

For further information you can refer these tutorials:

Have a look at byte code instrumentation. It allows you to intercept methods and change all kinds of things without necessarily having access to the source code (although it helps to have it for reference). Javassist is a great library to use along with the JVM Agent.

Cglib is another library that uses proxies to change the behaviour of targeted code, but I have found javassist easier to use.

This tutorial is a good start: http://rafaeloltra.com/developing-a-jvm-agent-for-bytecode-instrumentation-with-javassist-pt1/ . As well as the Javassist documentation: http://jboss-javassist.github.io/javassist/tutorial/tutorial.html

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