How to intercept a method in java

2019-02-24 03:55发布

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;
}

3条回答
叼着烟拽天下
2楼-- · 2019-02-24 04:19

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:

查看更多
我欲成王,谁敢阻挡
3楼-- · 2019-02-24 04:37

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

查看更多
爷的心禁止访问
4楼-- · 2019-02-24 04:42

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() {
}
查看更多
登录 后发表回答