Component Bindings

Introduction

While the best pratice is to have a single page controller under conversation per page or for a full multi page flow, there is a discrepancy between the scope length needed for the conversation and the scope length for associated component bindings. This discrepancy is not related to Orchestra; it is much more related to the JSF-specification itself.

Problem

The main problem is that component bindings need to be in a request-scoped backing-bean. The component tree is regenerated at every request. Longer component bindings are a possible cause for internal id clashes etc...

Now with what we have advocated so far, we have a single page controller/model object which is associated with the view. The page controller/model now is stateful, which is exactly what we wanted, however we need component bindings in this bean and those are referenced by the view. The bindings under normal circumstances inherit exactly the scope of the page controller.

Therefore the following construct is bound to fail:
<component binding="#{viewcontrollerbean.bindingattribute}" />					
				
due to the difference in scopes. At the first glance, this problem is impossible to solve. With more thoughts, Spring itself provides the solution. Since every bean referenced by the framework and the view layer is a Spring bean, we get the solution out of the "magical Spring toolset".

Solution

Spring in 2.0 has introduced a construct called aop-proxy. This is a special tag which can be embedded into beans which basically does nothing more than to weave a proxy object around an existing object which inherits the scope of the referencing bean. The inner part of the proxy or own bean then can have a scope of its own which can be smaller than the scope of the referencing object.

So how does this help: Lets look again at our example
<component binding="#{viewcontrollerbean.componentbindingmodel.bindingattribute}" />					
				
The accessor path has slightly changed, we have introduced a second bean; a model bean which specifically holds our component bindings.

What happens on the spring configuration side is simply the following:
<bean id="componentbindingmodel" scope="request" class="path.to.our.model.class">
   <aop:scoped-proxy />
</bean>

<bean id="viewcontrollerbean" scope="conversation.flash" ...>
      <property name="componentbindingmodel"
            ref="componentbindingmodel" />

</bean>
				
The associated component binding model class is a class which only holds the components as attributes and provides associated setter and getter methods.

What happens at call stage: The viewcontrollerbean is instantiated under conversation scope, the proxy object is generated and assigned depending on its lazy binding stage. At the request end, the content of the componentbindingmodel bean is dropped and only the empty proxy shell is referenced. At the next request - which references parts of the componentbindingmodel object - the content is initialized again and can be accessed. With this, it is possible to bind the request scoped component bindings to any long running scope no matter if they are custom conversation scopes or the session scope!