How to intercept a method in java

左心房为你撑大大i 提交于 2020-02-15 08:07:27

问题


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

回答1:


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() {
}



回答2:


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:

  • Spring AOP Example Tutorial – Aspect, Advice, Pointcut, JoinPoint, Annotations, XML Configuration.
  • Spring AOP + AspectJ annotation example.



回答3:


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



来源:https://stackoverflow.com/questions/31587931/how-to-intercept-a-method-in-java

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!