|
Table of Contents
Create Reflective ObjectsUp to this point of the tutorial, we have seen how to apply aspects to classes, altering their structure and/or behavior. But sometimes it is useful to alter the structure and/or behaviour of just one instance. If we only were limited to what we have seen we would have to create a empty subclass and apply the links to it. To avoid this kind of problems, Reflex provides an utility method Reflex.createObject, that is able to create a reflective instance of a class applying a especified set of links to it. APIThe signature of the method is: public static <T> T createObject( String aClassName, Object[] aArgs, ConfigurationObject aConfObject )
The first parameter is the class name we want to get an instance from. Then, the arguments to create the object must be specified. Finally, a
Let us review the (more interesting) part of the API of the public SLink addSMetaobject(SMetaobject aSMetaobject)
This method allow us to add a structural metaobject to the configuration. Notice that we do not have to specify a It returns a SLink that is associated with the specified structural metaobject. public BLink addBMetaobjectDefinition( MODefinition aMODef, Class aOp, OperationSelector aOpSelector )
This method allows to add a metaobject definition for the operation and operation selector specified. As in the
It returns the Example of UsageIn the Reflex distribution there is a complete example that uses all the methods listed above to create a reflective instance. The code can be found here.
Nevertheless, we are not going to review that example because we want to use one of the aspects we have seen in this tutorial to demostrate the use of this particuar API. We will take the tracing aspect as our example. We will apply it to just one instace of the MODefinition theMO = new MODefinition.SharedMO(System.out); ConfigurationObject theConfigObject = new ConfigurationObject(); theConfigObject.addBMetaobjectDefinition( theMO, MsgReceive.class, new DeclaredInOS("reflex.examples.fibonacci.app.Fibonacci") ); BLink theLink = theConfigObject.getBLinkFor(theMO); theLink.setControl(Control.BEFORE_AFTER); theLink.setCall( Control.BEFORE, System.out.getClass().getName(), "println", new BeforeParameter()) ); theLink.setCall( Control.AFTER, System.out.getClass().getName(), "println", new AfterParameter()) ); Here we use the same metaobject definition and link configuration as in the original example. The difference is that we do not have to:
Then if we use this object: System.out.println("--------------- Create Object -----------------------------"); Fibonacci theInstance = Reflex.createObject( Fibonacci.class, null, theConfigObject ); System.out.println("fib[5] = " + theInstance.get(5)); We should see output like the following:Before message receive: get([5]) Before message receive: get([4]) Before message receive: get([3]) Before message receive: get([2]) Before message receive: get([1]) After message receive: get is returning: [1] Before message receive: get([0]) ... After message receive: get is returning: [5] fib[5] = 5 However, if we invoke the method over a normal instace: System.out.println("--------------- Normal Object -----------------------------"); theInstance = new Fibonacci(); System.out.println("fib[5] = " + theInstance.get(5)); We do not get any tracing: --------------- Normal Object ------------------------------- fib[5] = 5 The complete code of this class (we do not need link providers here because the links are defined at runtime) is here. To run the example, the command is: Windows
%java -classpath
"lib\javassist.jar;build\reflex-core.jar;build\reflex-examples.jar"
reflex.examples.tutorial.CreateObjectTracingAspect
Linux
%java -classpath
"lib/javassist.jar:build/reflex-core.jar:build/reflex-examples.jar"
reflex.examples.tutorial.CreateObjectTracingAspect
Limitations
There are some limitations for this part of Reflex that are not present if we use link providers. All of them are related to the way the
|