Post on 14-Apr-2017
transcript
MetaProgramming With Groovy
AgendaWhat is MetaProgrammingMetaProgramming in GroovySimple DemoObjects In GroovyMOP Method InjectionMOP Method SynthesisMethod Mixins
What is MetaProgrammingFrom Wikipedia:
Metaprogramming is the writing of computer programs thatwrite or manipulate other programs (or themselves) as theirdata.
“Writing code that writes code”
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
MetaProgramming in groovy
MetaProgramming in groovyIn 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
Demo of MetaProgrammingInteger.metaClass.isEven = { -> // only (->) sign indicates that isEven() method is no argument method println delegate%2 == 0}
6.isEven()7.isEven()
Demo of MetaProgrammingWhen 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
MetaProgramming in groovyWhenever 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 classMetaPogramming does kill performance but it makes up for that with the dnamic features
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);}
Objects in GroovyGroovy 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
GroovyObject in ActionAll Groovy classes implement this interface
class Person{ def name def sleep() { println "sleeping"}}
>> groovyc Person.groovy>> javap –public Person
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.
Demo Of Invoke Method
This demo shows the working of invoke Method which is quite similar of how after before and around advices work
MOP Method InjectionIn 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
Capability of Injection● Adding properties using MetaClass● Adding constructor using MetaClass● Overriding methods using MetaClass
}
Injecting static methodInteger.metaClass.static.isEven = { number -> number%2 == 0}
Integer.isEven(1) // falseInteger.isEven(2) // true
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 = 9aNumber.metaClass.isEven = { -> delegate%2 == 0}
println aNumber.isEven() // falseprintln 2.isEven() // will throw MissingMethodException.
Integer.metaClass { isEven { -> delegate%2 == 0 } isOdd { -> delegate%2 != 0 } // other methods }
println 6.isEven() // trueprintln 6.isOdd() // false
Add multiple methods
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.
Demo of MethodMissing
Method Mixins● Inject methods from other types
● Works on classes and interfaces
● Doesn’t not work on instances
● Easier to use than Categories
Demo of Method Mixins
Applications● Dynamic finders● Builders● Custom DSL● Dependency Injection● Method injection● Interceptors● Generate mock objects for unit testing
MetaClasses in groovyMetaClassImpl: Default meta class, it's used in the vast majority ofcase.● 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.
Questions
Referenceshttp://groovy-lang.org/metaprogramming.html
http://igor.kupczynski.info/2013/12/07/groovy-method-resolution.html
http://www.slideshare.net/zenMonkey/metaprogramming-techniques-in-groovy-and-grailshttps://www.youtube.com/watch?v=UJhlp5P7Ec0
http://www.slideshare.net/ilopmar/metaprogramming-with-groovy
Thank You
Presented By:- Chetan Khare
For demo project please visit https://github.com/NexThoughts/groovy-meta-programming