如何拦截java中的方法

时间:2015-07-23 12:51:34

标签: java spring methods intercept

以下是方法:

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

以下是java文件中的方法调用:

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

我无法对这些文件进行任何更改,但我想截取该方法并添加一些代码(我也希望访问这些参数)

我在另一个java文件中编写的代码但没有成功:

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 个答案:

答案 0 :(得分:3)

使用aop编程。例如,尝试阅读有关AspectJ的内容。

Ex代码:

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

答案 1 :(得分:2)

面向方面编程(AOP)就是为此而设计的,您可以使用 AspectJ

  

AspectJ支持横切关注点的清晰模块化,例如错误检查和处理,同步,上下文敏感行为,性能优化,监视和日志记录,调试支持以及多对象协议。

或者当您使用Spring时,您可以使用Spring 2.0 AOP

  

Spring 2.0引入了一种使用基于模式的方法或@AspectJ注释样式编写自定义方面的更简单,更强大的方法。这两种样式都提供完全类型的建议和AspectJ切入点语言的使用,同时仍然使用Spring AOP进行编织。

这是如何声明一个方面:

@Aspect
public class NotVeryUsefulAspect {

}

这是如何声明一个pointCut:

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

有关详细信息,请参阅以下教程:

答案 2 :(得分:0)

查看字节码检测。它允许您拦截方法并更改各种事物,而无需访问源代码(尽管它有助于提供参考)。 Javassist是一个与JVM代理一起使用的优秀库。

Cglib是另一个使用代理来改变目标代码行为的库,但我发现javassist更容易使用。

本教程是一个好的开始:http://rafaeloltra.com/developing-a-jvm-agent-for-bytecode-instrumentation-with-javassist-pt1/。 以及Javassist文档:http://jboss-javassist.github.io/javassist/tutorial/tutorial.html