Want to Autowire your interceptors? Now you can!!


Want to Autowire your interceptors? Now you can!!

Posted by Luis Majano
Jan 18, 2008 00:00:00 UTC
Thanks to the autowire interceptor you are going now to be able to autowire your handlers/plugins and interceptors with any kind of objects from an IOC container like coldspring or lightwire. I just commited the update to the autowire interceptor and it works in the same way as handlers and plugins.

1. Declare the autowire interceptor

2. Add the autowire metadata property to your components: plugin, event handler or interceptor.

...

3. Add your setters/getters to your object.

That's it, easy as 1-2-3!!

Download now the nightly build.


Brian Kotek

Very nice! A few comments based on my quick look at how you're doing this:

You probably want an exclusive lock around the creation of the metadata itself in autowire.cfc. If two threads come in at the same time you could have all this work done twice and run into race conditions if one thread is rebuilding the dependencies while another is trying to resolve them.

You are caching some basic metadata about the dependencies for a given component type. I actually am caching references to the dependent components. This makes the actual bean injection faster because I don't have to do containsBean() checks or call getBean every time (which involves several lookup steps). I just loop over the dependent references and inject them.

I think you might get some fairly significant performance boost out of a similar approach, especially under load. Anyway, just my 2 cents! Regards.

Brian Kotek

Me again Luis, two quick clarifications about my comment:

First, I should have noted that the lock I'm proposing would be named based on the type being autowired (so its only single threading for autowires for the same target component type).

Second, I should note that getBean() only has the dependency checking overhead for non-Singletons or for Singletons that have not been created yet. So in most situations, getBean() is pretty fast. But there is still logic in there (as there must be), and if you can skip it altogether by keeping references to the dependent beans in your dependency cache it will indeed save some processing time.

Thanks, just wanted to be sure these two points were a bit more clear! :-)

Luis Majano

Actually they are clearer now!! Thanks Brian! I was still asking myself questions until I read your second comment and the light shined!!

So in conclusion on your second point, another performance boost would be to cache the dependencies that are called from the ioc container? Is that correct? That way, further dependencies are just injected and we do not have to go to the ioc container again?

I think I can go about this in two ways:

  1. The framework offers something called IOCObjectCaching in which the ioc proxy plugin caches the objects that are produced by the ioc container according to whatever cache metada they place on the objects themselves. This would permit the caching of the dependencies on the ioc plugin itself and the autowire interceptor would just retrieve from cache when necessary.

  2. Cache the dependencies on the autowire itself, but give documentation that IOCObjectCaching should not be performed, because then you will be caching in two places?

Does this make sense? your thoughts?

Brian Kotek

Yep. I'd say if you already have a place where references to bean instances obtained from the IOC container are kept, it would be fine to keep them there. Probably not much point is doing it in two places. My BeanInjector just holds a struct that maps the property name to the instance.

Luis Majano

Thanks Brian, the only thing I am seeing is that in order for the IOCObjectCaching to work, you must add two metadata parameters to your beans:

<cfcomponent name="myBean" cache="True" cacheTimeout="">

Once that metadata is in place in the bean and the ioc plugin asks the ioc container for the bean, it introspects it and caches it accordingly.

The only problem I see with the approach of caching the instances is if they are declared as singletons in coldspring. Because if they are, then they are already cached within coldspring, thus having the potential of duplicate objects: 1) Coldspring 2) the autowiring mechanism.

What are your thoughts on this?

I have gone around it by basically telling coldspring "singleton=false". What would your approach be?