【问题标题】:How to intercept a method in java如何在java中拦截一个方法
【发布时间】:2015-07-23 12:51:33
【问题描述】:

方法如下:

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

【问题讨论】:

  • 您说您不能更改 WebModuleUtil 类,但是使用该方法的类呢?你能改变它的调用方式吗?
  • 你需要编程一个方面。方面适合此类任务本身。

标签: java spring methods intercept


【解决方案1】:

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

示例代码:

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】:

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

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

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

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

    这是声明一个方面的方法:

    @Aspect
    public class NotVeryUsefulAspect {
    
    }
    

    这是声明切入点的方法:

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

    有关更多信息,您可以参考以下教程:

    【讨论】:

      【解决方案3】:

      查看字节码检测。它允许您拦截方法并更改各种事物,而不必访问源代码(尽管它有助于参考)。 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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-06-27
        相关资源
        最近更新 更多