In computing, aspect-oriented programming (AOP) is a programming paradigm in which secondary or supporting functions are isolated from the main program's business logic. It aims to increase modularity by allowing the separation of cross-cutting concerns, forming a basis for aspect-oriented software development.
AOP includes programming techniques and tools that support the modularization of concerns at the level of the source code, while aspect-oriented software development refers to a whole engineering discipline.
Aspect-oriented programming entails breaking down a program into distinct parts (so-called concerns, cohesive areas of functionality). All programming paradigms support some level of grouping and encapsulation of concerns into separate, independent entities by providing abstractions (e.g. procedures, modules, classes, methods) that can be used for implementing, abstracting and composing these concerns. But some concerns defy these forms of implementation and are called crosscutting concerns because they "cut across" multiple abstractions in a program.
Assume that for whatever reason we want to know the time before and after each call to a method in a class called SimplePOGO. To accomplish this task in Groovy, we simply implement theGroovyInterceptable
interface and theinvokeMethod()
like this:
generaciondecodigos@nereida:~/Lgroovy/objects$ cat -n AOP1.groovy 1 class SimplePOGO implements GroovyInterceptable { 2 void simpleMethod1(){ 3 System.out.println("simpleMethod1() called") 4 } 5 6 void simpleMethod2(String param1, Integer param2){ 7 System.out.println("simpleMethod2(${param1},${param2}) called") 8 System.out.println("sleeping...") 9 Timer.sleep(2000) 10 } 11 12 def invokeMethod(String name, args){ 13 System.out.println("time before ${name} called: ${new Date()}") 14 15 //Get the method that was originally called. 16 def calledMethod = SimplePOGO.metaClass.getMetaMethod(name, args) 17 18 //The "?" operator first checks to see that the "calledMethod" is not 19 //null (i.e. it exists). 20 calledMethod?.invoke(this, args) 21 22 System.out.println("time after ${name} called: ${new Date()}\n") 23 } 24 } 25 26 simplePogo = new SimplePOGO() 27 simplePogo.simpleMethod1() 28 simplePogo.simpleMethod2("stringParam", 24) 29 simplePogo.simpleMethod3(1, 2, 4)
invokeMethod()
es llamado cada vez que cualquiera de sus métodos es llamado.
Tanto si el método existe como si no: en el ejemplo la
llamada a simplePogo.simpleMethod3
será también interceptada.
metaClass
de la clase SimplePOGO
es de la clase
HandleMetaClass
y representa la metaclase asociada con SimplePOGO
.
getMetaMethod
:
public MetaMethod getMetaMethod(String name, Object[] args)
It retrieves an instanceMetaMethod
for the givenname
andargs
values, using the types of the argument values to establish the chosen MetaMethod. It returns a MetaMethod ornull
if it doesn't exist
def calledMethod = SimplePOGO.metaClass.getMetaMethod(name, args)deja en
calledMethod
un objeto MetaMethod
que referencia
a un método de la clase SimplePOGO
cuyo nombre es name
y cuya firma
coincide con args
.
calledMethod
el MetaMethod
que esta siendo llamado
pasamos a invocarlo usando invoke
cuyo prototipo es:
public abstract Object invoke(Object object, Object[] arguments)
generaciondecodigos@nereida:~/Lgroovy/objects$ groovy AOP1.groovy time before simpleMethod1 called: Tue Feb 23 16:18:11 WET 2010 simpleMethod1() called time after simpleMethod1 called: Tue Feb 23 16:18:11 WET 2010 time before simpleMethod2 called: Tue Feb 23 16:18:11 WET 2010 simpleMethod2(stringParam,24) called sleeping... time after simpleMethod2 called: Tue Feb 23 16:18:13 WET 2010 time before simpleMethod3 called: Tue Feb 23 16:18:13 WET 2010 time after simpleMethod3 called: Tue Feb 23 16:18:13 WET 2010
Esta técnica es adecuada siempre que no se de una de estas circunstancias: