Brian's Waste of Time

Mon, 01 Dec 2003

Intercept Just Got Faster

Chris Nokleberg, one of the cglib developers, sent a patch in to optimize the use of cglib's proxies in the interceptor library I posted this morning. I replaced the tarballs on my site with the new improved version. No API changes, but the patch removed the last remnant of reflection in the invocation sequence.

Thank you!

2 writebacks [/src/java/commons-intercept] permanent link

Intercept Library Initial Release

This past weekend, my girlfriend being out of town, I got to hack a lot. It was nice. At one point I needed a general purpose interceptor tool and went digging through the various ones out there. XWork is tightly coupled to its Command stuff. Spring is tightly coupled to its IoC stuff and XML configuration. HiveMind is temporarily unavailable. AspectJ and AspectWerkz are not simple interceptor libraries, they are full fledged languages for all practical purposes.

So, in good old itchy fashion I tossed together a bare-bones interception library. It doesn't do IoC, it doesn't do XML configuration, it doesn't include a web application framework, it doesn't include an EJB container, or service definitions, or dependencies on commons-*. It just does interception of arbitrary method calls with arbitrary interceptors in 332 lines of code =)

It provides all the spiffies I want, and that others seem to want in very few classes. Its very optimized for wrapping objects and executing invocation stacks (ie, intercepted method calls) rather than for adding new interceptors. Making a typical call to an intercepted method doesn't involve any reflection (it uses cglib). The first time an instane of a given class is wrapped it is slow (bytecode generation) and when a new interceptor is added it is slow (needs to traverse its cache and figure out what it applies to) but the common stuff is fast and that's what counts =)

Using it is pretty easy, and works like:


    InterceptionBroker broker = new InterceptionBroker();
    broker.addInterceptor(new LoggingInterceptor(), new Signature()
    {
        public boolean match(Method m)
        {
            // Match every method call on every object
            return true;
        }
    });
    
    Map example = new HashMap();
    Map same = broker.wrap(example);
    // same is the interception wrapped version of example
    example.put("foo", "bar");  // Will not be intercepted
    same.get("foo");            // Will be intercepted and logged
It supports singleton interceptors like the above example, or per-invocation style interceptors where it creates a new one for each invocation.

Source code , Binary Distribution and javadocs are all available. It's BSD licensed for now. If anyone else uses it or contibutes then I may look into moving it into the Apache Commons Sandbox, but I won't bother as long as I am the sole contributor =)

5 writebacks [/src/java/commons-intercept] permanent link