2012-05-18 12 views
5

Chcę napisać prosty agent java, który może wydrukować nazwę metody wywołanej przez program java oprzyrządowany.Jak przyrządzić metody java?

Na przykład, mój program java Chcę instrumentu jest:

public class TestInstr { 

public static void sayHello() { 
    System.out.println("Hello !"); 
} 

public static void main(String args[]) { 
    sayHello(); 
    sayHello(); 
    sayHello(); 
} 

} 

Chciałbym wyświetlić coś takiego:

method sayHello has been called 
Hello ! 
method sayHello has been called 
Hello ! 
method sayHello has been called 
Hello ! 

dzięki za pomoc!

+0

http://stackoverflow.com/questions/10562769/record-every-method-execution –

Odpowiedz

8

Do tego celu można użyć biblioteki instrumentów, na przykład Javassist.

Podam przykład dla jednej metody, można wydłużyć ten do wszystkich metod wykorzystujących Javassist lub refleksji:

ClassPool pool = ClassPool.getDefault(); 
CtClass cc = pool.get("TestInstr"); 
CtMethod m = cc.getDeclaredMethod("sayHello"); 
m.insertBefore("{ System.out.println(\"method sayHello has been called\"); }"); 
cc.writeFile(); 

Sprawdź ten link do informacji: http://www.csg.ci.i.u-tokyo.ac.jp/~chiba/javassist/tutorial/tutorial2.html#intro

+0

Dzięki! Przyjrzę się javassistowi. – kdelemme

1

W metodzie można dodać

public class TestInstr { 

public static void sayHello() { 
System.out.println("method sayHello has been called"); 
System.out.println("Hello !"); 
} 

public static void main(String args[]) { 
sayHello(); 
sayHello(); 
sayHello(); 
} 
} 

Można to wykorzystać, aby otrzymać aktualną metodą

public String getCurrentMethodName() { 
StackTraceElement stackTraceElements[] = 
     (new Throwable()).getStackTrace(); 
return stackTraceElements[1].toString(); 
} 

Nie jestem pewien, czy to jest to, czego szukasz.

4

Wydaje mi się pamiętać, że AspectJ może robić takie rzeczy; Nie mam z tym żadnego doświadczenia, więc odkrywanie możliwości należy do Ciebie! : D

+0

Nie użyłem tego, ale z tego, co słyszałem, zgadzam się, że przydatne może być spojrzenie na AspectJ. – SJuan76

+1

Również jeśli chcesz uzyskać pełną kontrolę, użyj cglib lub javassist. Ale rozważ użycie Spring i "around-advice" – Xeon

1

Nie sądzę, że to łatwe.

Jedyną opcją, o której mogę pomyśleć, to zaimplementowanie programu ładującego klasy i zastąpienie oryginalnych klas tworzonymi przez ciebie skrótami (Hibernate/JPA robi coś takiego dla leniwego ładowania). Stuby wykonają wymaganą operację, a następnie wywołają oryginalne klasy w celu wykonania pracy. Oznaczałoby to duże obciążenie (rozmowy refleksyjne nie są tanie).

0

Jeśli potrzeba jest po prostu Aby zarejestrować metodę, która została wywołana lub nie, wtedy programowanie zorientowane na aspekt jest dokładnie tym, czego potrzebujesz, bez względu na AspectJ (statyczny) lub Spring AOP (dynamic), oba zapewniają potężną zdolność do tego. Jednak możesz potrzebować niektórych bibliotek instrumentów na wypadek, gdybyś chciał zrobić więcej rzeczy na instrumencie, takich jak śledzenie czasu wykonania, wywoływanie ścieżki. Mam nadzieję, że to pomaga.

Powiązane problemy