Hi, I've been looking at how Spring implements its custom scopes feature, and how this interacts with JSF.
Can someone verify that I understand this right? The class org.springframework.web.jsf.DelegatingVariableResolver is configured as the var-resolver for a JSF webapp, via faces-config.xml. This class first delegates to the standard JSF var-resolver, which directly looks in request, session and app scopes for the name. If it finds the var, it just returns - this is pretty quick. If it fails, it looks in its config for the name, and if found then it creates the bean, adds it to the scope and returns - again fairly quick. If this process fails (ie bean not in request, session or app scope and no definition in the standard JSF manner) then DelegatingVariableResolver calls org.springframework.beans.factory.support.AbstractBeanFactory.getBean(...). This code first checks its singleton cache. If it doesn't find an already-created bean there then it looks up its bean definition. * If the type is "singleton" then it creates a new instance, puts it in the singleton cache then returns. * If the type is "prototype" then it creates a new instance, and returns it without caching it anywhere. * If the type is a custom scope then it finds the appropriate registered scope-handler and invokes its get method, passing an ObjectFactory object that knows how to create an instance from the bean definition it has already located. For the request and session scopes, the scope-handlers first look in the request or session - but will never find anything, otherwise the JSF var-resolver would have found it earlier. So they use the ObjectFactory to create the bean and store it in the request/session. On later attempts by JSF to look up this bean, the standard JSF var-resolver will find it immediately in the request/session which is nice and efficient. For the "conversation" scope, however, things are not so efficient. The JSF variable resolver will never find the bean in request/session. The AbstractBeanFactory.getBean method will not find the object in the singleton cache either. It will therefore have to locate the bean definition, then invoke the o.a.m.orchestra.conversation.spring.SpringConversationScope.get method. This method locates the spring bean definition *again* in order to find the conversation name, then retrieves the current ConversationContext, from that the right conversation, and then from the conversation the actual bean. When the bean already exists, it is then returned and otherwise it is created and added to the conversation. This does seem a pretty slow process to go through for every EL reference to a conversation-scoped bean. I don't mean to criticise, and I certainly don't have any optimisations to suggest ATM; I would just like to know if I've understood this right, or whether I have missed something that optimises access to conversation-scoped beans. It seems to me that: * access to Prototypes can't really be optimised as they are created each time by definition * access to Singletons is efficient as they are cached * access to request/session vars is not very good when using Spring alone, but because the JSF var-resolver looks into request and session objects this allows the objects to be retrieved without passing through spring at all. * access to conversation vars is going to be slow because every lookup requires a pass through Spring, resulting in quite a lot of processing - including lookup of the bean def, which can be quite complicated. Regards, Simon
