Flapper: An extension library for AOP with Parsley

I’ve just thrown a quick project up on Google Code for allowing simple AOP style programming with Parsley:

Flapper

The project aims to allow simple registration of AOP interceptors by registering a metatag with an interceptor.

It uses the awesome as3-commons bytecode library for proxy generation

Configuration

The aim is to have simple configuration.  You activate Flapper by simply declaring  AspectSupport in your parsley context:

        <parsley:ContextBuilder>
            <parsley:FlexConfig type="{ParsleyConfig}" />
            <tag:AspectSupport>
                <tag:MetatagAspectDefinition metatag="Log" aspect="{new LoggingAspect()}" />
            </tag:AspectSupport>
        </parsley:ContextBuilder>

In this example, I’m registering the Log metatag with my LoggingAspect.

Now, any class which has a method annotated with Log will be proxied, and the LoggingAspect will get invoked before the actual method itself.

Eg:

    public class Calculator
    {
        [Log]
        public function add(a:int,b:int):int
        {
            return a + b;
        }

    }

The aspects themselves are also extremely simple, implementing an Aspect interface.

Here’s my LoggingAspect:


    public class LoggingAspect implements Aspect
    {
        public function intercept(pointCut:ProceedingJoinPoint):void
        {
            trace(pointCut.targetMember.localName + " called with params: " + pointCut.arguments.join(","));
            pointCut.proceed();
            var returnValueString:String = pointCut.returnValue ? pointCut.returnValue.toString() : "null";
            trace(pointCut.targetMember.localName + " returned " + returnValueString );
        }
    }

This simply traces out the method name that was called, and the arguments that were passed in.

Usage

That’s all the configuration that’s required.  Now, any time I call calculator.add(), the aspect will trace out the call to the console window.

Note – classes that will be proxied must be decalred using Parsley’s Object tag, rather than as an instance.

Eg:

    <fx:Declarations>
        <!-- Don't do this -- it won't work -->
        <sample:Calculator />

        <!-- Instead, decalre using the Object tag -->
        <parsley:Object type="{Calculator}" />
    </fx:Declarations>

Usage from here is no different than with any other injected class.

Example:

            [Inject]
            public var calculator:Calculator;

            private function addNumbers():void
            {
                 // Results in a message being traced out "Called add with arguments: 2,3"
                calculator.add(2,3)
            }

The project and a demo are available to be checked out here. It’s still fairly early days, and the project hasn’t really been tested – but feel free to grab it and have a play.

Important Credit

This whole project took 2 nights to write.  The main reason it was so quick and simple  is because all the hard work has already been done by two awesome existing projects.

The as3-commons team have done an amazing job on the project, but also in providing thorough clear documentation.

Equally so, Jens Halm has done an outstanding job on Parsley, making the framework so easy to extend, with a solid API, and killer docs.  Not to mention he’s extremely responsive in the forums.  Both these projects rock.

Update:

I’ve updated this blog post to reflect the move to the Aspect interface, where previously I was using the ascommons-bytecode IInterceptor.  This has made chaining Aspects easier.  Note – I’m still using ascommons-bytecode underneath, but it’s now abstracted away a little more.

Tagged , ,

7 thoughts on “Flapper: An extension library for AOP with Parsley

  1. Roland Zwaga says:

    Nice work! Really stoked to see as3commons-bytecode getting adopted so early. Keep up the great work!
    Proxying has been finished completely since the last release of v0.9.4 (which fixed proxying of methods that have …rest arguments declared). There will be some more interesting stuff before v1.0, so keep an eye on the repository 🙂

    cheers!

    Roland

  2. I’m impressed with this too, great work! One question though – is there a way to apply aspects to, say, all methods in a class?

  3. Josh Handcock says:

    Hey Marty,

    Great work.
    This AOP support you’ve developed for Parsley has come in very useful on my current project.

    Cheers
    Josh

    • Marty Pitt says:

      Cool – glad you like it! Check out the latest from the weekend, which adds support for proxying any class / method based on a pattern, which removes the need for the metatags.

  4. George Cook says:

    Dude, this aop support is excellent. Guys on my team will love it. OR ELSE 😀

Leave a comment