I’m a big fan of Peter Bell’s Lightwire framework. I’ve been using it for quite a while for dependency injection and I love it. However, it’s been lacking a key feature that ColdSpring has: Aspect Oriented Programming (AOP). No more. I’ve taken some time to add some AOP magic to Lightwire and although I haven’t been able to test much yet, it’s looking pretty good so far.
First things first, I gotta give much credit to the developers of ColdSpring. My implementation was very much inspired by their work and made it that much easier to get things done. For users of ColdSpring, things will look rather familiar, I’ve implemented Before, After, Around, and Exception advices in Lightwire, all of which are supported by ColdSprings, albeit some with slightly different names.
For users of Lightwire, AOP is implemented with the same simplicity as the rest of the framework and is a breeze to use. Advices are defined in the configuration bean in a similar way as beans. There is a method for each type of advice: addBeforeAdvice(), addAfterAdvice(), addAroundAdvice(), and addExceptionAdvice(). The arguments for these four methods are the same, so I’m just going to show addBeforeAdvice():
addBeforeAdvice( beanName, // The name of a Lightwire bean that you want to give advice to adviceBeanName, // The name of a Lightwire bean that provides advice [methods], // Optional, methods that the advice applies to; defaults to *, which means all, can be a comma delimited list of method names [adviceMethod] // Optional, name of the advice method, which defaults to the advice type (before, after, around, or exception) if not specified );
Note that neither of the beans specified above need to extend anything. They can be any bean, any class, extending anything else you want. Now, let’s take a look at what parameters the advice bean methods should receive. Note that I’m going to use the default method names, but you can set the advice method to whatever you want using the optional adviceMethod argument.
before( method, // The method that triggered the advice args, // The arguments passed into the method (struct) target // The bean that contains the method that triggered the advice ); after( method, // The method that triggered the advice args, // The arguments passed into the method (struct) target, // The bean that contains the method that triggered the advice [returnVal] // Will return a value if the triggering function returned something ); around( AdviceDispatcher // An AdviceDispatcher object, which will be further discussed below ); exception( method, // The method that triggered the advice args, // The arguments passed into the method (struct) target, // The bean that contains the method that triggered the advice error // The cfcatch struct for the error );
While you are not required to define the arguments (you might not need one or more), if you do define them be sure to spell them right because they are passed as named arguments, not numbered.
Now, the around() method is special because it receives a single object, AdviceDispatcher, which is essentially the same as the MethodInvocation object in ColdSpring. This object gives you full control over what will happen with your method call. Within your around device, you can trigger the target method execution by calling the run() method of the AdviceDispatcher object. Beyond that, you can put any code you want around it, to define code to run before and after. Your code can also make it so the method will not run in certain situations, all you have to do is create a situation where the AdviceDispatcher.run() method does not run. Here is the definition of the AdviceDispatcher object:
lighwire.aop.AdviceDispatcher METHOD RETURN TYPE DESCRIPTION run() void Executes the target method getTarget() object Returns the target bean object getMethod() string The name of the target method getArguments() struct The arguments passed to the target method
That’s it! This is pretty much all you need to know to do AOP with Lightwire. Now I do realize that this article assumes prior knowledge of Lightwire and AOP, so I’m hoping to blog some tutorials on both of those topics to make things clearer for those just getting started with those.
I’ve been talking with Peter Bell and if my changes prove to be any good, which I hope they will, they could eventually make it into the core product on riaforge. For now, you can download my modified Lightwire by clicking the link at the bottom. I’ve included an aopSample folder where you can see some tests. They’re not the best and just output text, but it’s better than nothing for now. You can unzip the folder in your webroot, or you can unzip it anywhere on your web server and modify the component paths in the aopSample/index.cfm file. I’ve been testing this on CF 8, IIS, so if you run into problems and are running on a different platform let me know so I can get them sorted out.



