2009-08-04 21 views

Odpowiedz

2

Czy spojrzałeś na Groovy AOP? Jest bardzo mało documentation, ale pozwala na definiowanie punktów i porad w koncepcyjnie podobny sposób jak w AspectJ. Wystarczy popatrzeć na unit tests dla niektórych więcej przykładów

Poniższy przykład będzie pasował wszystkie połączenia do wszystkich rodzajów tkanin i zastosuj porady przed kontynuowaniem:

// aspect MyAspect 
class MyAspect { 
    static aspect = { 
    //match all calls to all calls to all types in all packages 
    def pc = pcall("*.*.*") 

    //apply around advice to the matched calls 
    around(pc) { ctx -> 
     println ctx.args[0] 
     println ctx.args.length 
     return proceed(ctx.args) 
    } 
    } 
} 
// class T 
class T { 
    def test() { 
    println "hello" 
    } 
} 
// Script starts here 
weave MyAspect.class 
new T().test() 
unweave MyAspect.class 
1

Przede wszystkim nadrzędnymi Object.metaClass.invokeMethod nie działa, ponieważ gdy Groovy próbuje rozwiązać wywołanie metody dla typu X, sprawdza metaClass X, ale nie metaClass jego rodzica (klas). Na przykład, następujący kod wypisze „metoda intValue przechwycone”

Integer.metaClass.invokeMethod = {def name, def args -> 
    System.out.println("method $name intercepted") 
} 

6.intValue() 

// Reset the metaClass 
Integer.metaClass = null 

ale ten kod nie będzie:

Object.metaClass.invokeMethod = {def name, def args -> 
    System.out.println("method $name intercepted") 
} 

6.intValue() 

// Reset the metaClass 
Object.metaClass = null 

Twoje pytanie brzmiało: „Czy to możliwe, aby przechwytywać wszystkie metody zwane w aplikacji? ”, ale może być nieco dokładniej o to, czy chcesz:

  • Intercept wzywa do Groovy metody, metody Java lub zarówno
  • Intercept wzywa do zaledwie twoi metody Groovy/Java czy też przechwytywanie połączeń do klas bibliotecznych Groovy/Java

Na przykład, jeśli chcesz tylko przechwytywanie połączeń do swoich Groovy klas, można zmienić swoje zajęcia do wdrożenia GroovyInterceptable. Zapewnia to wywołanie metody invokeMethod() dla każdej metody wywoływanej na tych klasach. Jeśli charakter przechwytywania (tj. Elementy, które chcesz wykonać przed/po wywołaniu wywoływanej metody) jest taki sam dla wszystkich klas, możesz zdefiniować invokeMethod() w oddzielnej klasie i użyć @Mixin, aby zastosować ją do wszystkich swoich zajęć.

Ewentualnie, jeśli chcesz przechwytywać połączenia z klasami Java, powinieneś sprawdzić numer DelegatingMetaClass.

+0

Chciałbym móc przechwycić wywołania metod Groovy i Java. – Geo

+0

Następnie powinieneś użyć DelegatingMetaClass lub pełnowymiarowego framework'a AOP, takiego jak groovy-aop lub AspectJ –

+0

Nie można przechwytywać * wszystkich * wywołań metod za pomocą metaClass, ponieważ metody Java wywoływane z Java nie będą przesyłane przez wysyłkę Groovy. Więc jeśli masz klasę Java wywołującą inną klasę Java, nie możesz przechwycić tego połączenia bez użycia jakiegoś AOP lub czegoś podobnego. – noah