2015-07-23 10 views
4

Вот метод:Как перехватить метод в Java

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

Вы говорите, что вы не можете изменить класс WebModuleUtil, но как насчет классов, которые используют этот метод? Не могли бы вы изменить способ его вызова? –

+0

вам необходимо запрограммировать аспект. Аспекты подходят для такой задачи. –

+0

@Pablo Нет, я не могу –

ответ

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

Аспект-ориентированное программирование (АОП) производится для этой цели, вы можете использовать AspectJ:

AspectJ позволяет чистой модуляризацию многоплановых проблем, таких как ошибки проверка и обработка, синхронизация, контекстно-зависимое поведение, оптимизация производительности, мониторинг и ведение журнала, поддержка отладки и многообъектные протоколы.

Или, как вы используете Spring вы можете использовать Spring 2.0 AOP:

Spring 2,0 вводит более простой и эффективный способ написания пользовательских аспектов с использованием либо подхода основанного на схеме или стиль аннотаций @AspectJ. Оба эти стиля предлагают полностью типизированные советы и использование языка pointcut AspectJ, в то же время используя Spring AOP для ткачества.

Это как объявить аспект:

@Aspect 
public class NotVeryUsefulAspect { 

} 

И это, как объявить Pointcut:

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

За дополнительной информацией вы можете обратиться к обучающим:

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