Message-ID: <616267320.1780.1386949885758.JavaMail.firstname.lastname@example.org> Subject: Exported From Confluence MIME-Version: 1.0 Content-Type: multipart/related; boundary="----=_Part_1779_2005692097.1386949885757" ------=_Part_1779_2005692097.1386949885757 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Content-Location: file:///C:/exported.html
This is an example of how to replace a MetaClass to adjust the d= efault behavior. Each groovy object has a metaClass that is used to manage = the dynamic nature of the language. This class intercepts calls to groovy o= bjects to ensure that the appropriate grooviness can be added. For example,= when an object is constructed, the MetaClass's invokeConstructor()is calle= d. One feature of the invokeConstructor allows us to create groovy ob= jects using a map argument to set the properties of the object (new X([prop= 1: value1, prop2: value2])).
These solutions perform complete replacements, where as a more scoped so= lution can be found at Using the Proxy Meta Class.
This technique installs the meta class at runtime using the InvokerHelpe= r to gain access to the registry which allows us to change the meta class i= nstance that is in use. The behaviour for objects created before the change= depends on whether they are Java or Groovy objects. Groovy objects &= quot;cache" their metaclass, so once they're created, changing the reg= istry has no effect. However, Java objects don't have a cache, so acc= esses to them always start with a trip to the registry, meaning any registr= y changes affect existing and new instances alike.
This sample code overrides the invokeMethod method to augment the behavi= or but there are other options that you can choose from like set and getAtt= ribute, invokeStaticMethod and invokeConstructor. The complete list can be = found in the Groovy's source release in "src/main/groovy/lang/Delegati= ngMetaClass.java".
Package Name Convention Solution
This second solu= tion offers a more consistent augmentation of existing classes. There are n= o risks of unpredictable results from methods. The idea is that any package= .class can have a custom meta class loaded at startup time by placing it in= to a well known package with a well known name.
So your class Foo in package "bar" could have a custom meta cl= ass FooMetaClass in package "groovy.runtime.metaclass.bar".
The following example shows how we can change the behavior of the String= class. Firstly the custom meta class, similar to the implementation above = except that it needs a MetaClassRegistry argument in its constructor.
The actual class that uses the enhanced features is now very simple. Not= ice that there are no extra imports or any work with the meta class. The me= re package and name of the class tells the groovy runtime to use the custom= meta class.
So what would happen if you used both techniques. Assume that the packag=
e convention class exists in your class path and you create and set another=
meta class. The answer is that the last setMetaClass that you did applies =
to the usages of all instance of the effected type.