Groovy provides metaprogramming capabilities through its Meta-Object Protocol (MOP). The MOP allows dynamically injecting, synthesizing, and mixing methods at runtime. This is done by manipulating metaclasses, which contain metadata about classes and allow intercepting method calls. Demonstrations show adding methods to classes like Integer to check for evenness, intercepting method calls, and mixing methods from other types. Metaprogramming with Groovy's MOP provides flexibility to dynamically modify classes and their behavior.
3. What is MetaProgramming
From Wikipedia:
Metaprogramming is the writing of computer programs that
write or manipulate other programs (or themselves) as their
data.
“Writing code that writes code”
4. MetaProgramming in groovy
● Groovy provides this capability through the Meta-Object Protocol
(MOP).
● We can use MOP to invoke methods dynamically and also synthesize
classes and methods on the fly
6. MetaProgramming in groovy
In Groovy Language, every object has an object of MetaClass class with name
metaClass. This metaClass object is responsible for holding all the information
related to that object. Whenever you perform any operation on that object,
Groovy’s dispatch mechanism routes the call through that Metaclass
object(metaClass). So if you want to change the behaviour of any object/class,
you will have to alter the MetaClass object attached to that class/object, and it will
alter the behaviour of that class/object at run time.
Metaprogramming is to extend the syntax and vocabulary of program at runtime
as we please dynamically that is exactly what metaprogramming really is all about
Gradle and grails are great example of metaprogramming in groovy
8. Demo of MetaProgramming
When you inject a method into class the injection process hands that delegate to
closure and delegate is the instance on which method is going to run .
We can say delegate is reference of that object who is invoking that isEven()
method.
Within a closure it is meaningless to use this because this refers to closures
Delegate represents the contextual object in which code is running
9. MetaProgramming in groovy
Whenever we call a method of class/object, it first gets information of that object
from metaClass attached to it, and then calls the appropriate method. In above
program we are asking Integer.metaClass, that there is an isEven() method in
integer class, whose definition is followed by it. Now when we will call
“anyInteger.isEven()”, it will excute isEven() method and will return true/false
accordingly, e.g.
The method does not add up in jvm but is called from meta class
MetaPogramming does kill performance but it makes up for that with the dnamic
features
10. Objects in Groovy
● Plain Old Java Objects (POJOs) - instances of regular java objects created on
JVM.
● Plain Old Groovy Objects (POGOs) - subclasses of GroovyObject. An
interface defined as follows.
public interface GroovyObject {
Object invokeMethod(String name, Object args);
Object getProperty(String property);
Object setProperty(String property, Object newValue);
MetaClass getMetaClass();
void setMetaClass(MetaClass metaclass);
}
11. Objects in Groovy
Groovy Interceptors - subclasses of GroovyInterceptable
● public interface GroovyInterceptable extends GroovyObject {}
With a POGO it is simple. You need to call its setMetaClass method and a
reference to this metaclass is stored within the object. With POJO this is
impossible - they are not designed to store a metaclass reference. For this reason
Groovy maintains an application wide MetaClassRegistry which maps
java.lang.Classes to metaclasses.
http://igor.kupczynski.info/2013/12/07/groovy-method-resolution.html
12. GroovyObject in Action
All Groovy classes implement this interface
class Person
{
def name
def sleep() { println "sleeping"}
}
>> groovyc Person.groovy
>> javap –public Person
13. Intercepting methods using MetaClass
● Groovy maintains a meta class of type MetaClass for each class.
● If we can't modify the class source code or if it's a Java class we can
modify the meta-class.
● We can intercept methods by implementing the invokeMethod()
method on the MetaClass.
14. Demo Of Invoke Method
This demo shows the working of invoke Method which is quite similar of how after
before and around advices work
15. MOP Method Injection
In Groovy we can “open” a class at any time.
Method Injection at code-writing time, we know the names of
methods we want to add.
Different techniques:
● MetaClass
● Categories
● Extensions
● Mixins
16. Capability of Injection
● Adding properties using MetaClass
● Adding constructor using MetaClass
● Overriding methods using MetaClass
}
18. Injecting to a instance
isEven() method is added to all the Integer objects, if we want to add isEven() in a
particular object only then we have to use that object reference
Integer aNumber = 9
aNumber.metaClass.isEven = { ->
delegate%2 == 0
}
println aNumber.isEven() // false
println 2.isEven() // will throw MissingMethodException.
20. MOP Method Synthesis
● Dynamically figure out the behaviour for methods upon invocation.
● A synthesized method may not exist as a separate method until we
call it.
● invokeMethod, methodMissing and propertyMissing.
● “Intercept, Cache, Invoke” pattern.
25. MetaClasses in groovy
MetaClassImpl: Default meta class, it's used in the vast majority of
case.
● ExpandoMetaClass: allow the addition or replacement of methods,properties
and constructors on the fly.
● ProxyMetaClass: Can decorate a meta class with interceptioncapabilities.
● Other meta classes used internally and for testing.