Issue Details (XML | Word | Printable)

Key: SPR-1420
Type: Improvement Improvement
Status: Open Open
Priority: Major Major
Assignee: Unassigned
Reporter: Keith Garry Boyce
Votes: 0
Watchers: 3
Operations

If you were logged in you would be able to see more operations.
Spring Framework

Add class structure to allow auto assembly of object graph in a way that is independent from object retreival implementation.

Created: 26/Oct/05 05:13 PM   Updated: 31/May/06 05:36 AM
Component/s: SpringWEB
Affects Version/s: 1.2.5
Fix Version/s: None

Time Tracking:
Not Specified

File Attachments: 1. Zip Archive springInjector.zip (7 kB)



 Description  « Hide
I implemented this for spring webflow (http://opensource2.atlassian.com/projects/spring/browse/SWF-9) and now I also implemented it for spring mvc...

maybe it can be included

Objective:
I find in almost all situations that the bulk of work in building a web app is to collect data from varying locations and ultimately construct an object graph that you can then persist or use for querying. This is especially true if using hibernate or another ORM tool.

Conclusion:
The proposed code below accomplishes that so that by the time you get to the action the populated objects would already be pre-populated and waiting for you in the scope you specify. So the action code would then be very simple or non-existent.

Summary:
The current FormAction only allows the creation of one form object per action. My thought is that if using hibernate or another ORM tool what you want instead is multiple objects (one per each domain object) so that at the time you run the action the object graph will already be created and all you need to do is extract it from the context and use it to query or persist. This avoids the bulk of the work generally in actions to assemble domain objects.

So basically this is IoC for a scope object to either create object in scope and set properties, set property on object already in specified scope or add object to collection of an object already in specified scope.


Below is illustration of pattern. I use it in a portlet application but a ServletAttributeResolver can simply be created as well as I did in webflow version...

Here is the idea from the portlet side:

  <bean id="portletModeControllerMapping"
        class="org.springframework.web.portlet.handler.PortletModeHandlerMapping">
    <property name="portletModeMap">
      <map>
        <entry key="view">
          <ref bean="viewModeFrontController" />
        </entry>
      </map>
    </property>
      <property name="interceptors">
         <list>
          <ref bean="topicDetailsRequestDTOInjector"/>
            <ref bean="openSessionInViewInterceptor"/>
         </list>
      </property>

  </bean>

This is the handler of which there is an equivalent handler for dispatcher servlet.

  <bean id="viewModeFrontController"
        class="com.xxx.contactus.spring.mvc.action.ContactUsController">
         <property name="contentPage" value="contactUs.Select.Topic.view"/>
         <property name="contactUsService">
<ref bean="contactUsService"/>
</property>
  </bean>

This is a simple abstract controller...

and here is the injector which is simply a form controller that can be used as an interceptor

<bean id="topicDetailsRequestDTOInjector" class="org.springframework.portlet.mvc.injector.ContextInjector">
    <property name="attributeResolvers">
       <map>
         <entry key="type">
           <bean class="org.springframework.portlet.mvc.injector.PortletAttributeResolverImpl">
             <property name="fromObject" value="application_user.type"/>
             <property name="attributeSourceChain"
                             value="applicationSession"/>
           </bean>
         </entry>
         <entry key="specialty">
           <bean class="org.springframework.portlet.mvc.injector.PortletAttributeResolverImpl">
             <property name="fromObject" value="application_user.specialty"/>
             <property name="attributeSourceChain"
                             value="applicationSession"/>
           </bean>
         </entry>
       </map>
    </property>
<property name="commandName"><value>topicDetailsRequestDTO</value></property>
<property name="commandClass"><value>com.xxx.contactus.dto.TopicDetailsRequestDTO</value></property>
</bean>




I have attached the source. It can be used as is for spring portlet mvc and with a simple adaptation it can be used also for servlet type controllers. I just didn't do it because I am sure you guys will have ideas how to make it better.



 All   Comments   Work Log   Change History   FishEye   Builds      Sort Order: Ascending order - Click to sort in descending order
Keith Garry Boyce added a comment - 26/Oct/05 05:14 PM
Here are the source files

Thomas Whitmore added a comment - 03/Feb/06 01:50 AM
Hi Keith, Juergen,

I'd like to point out that Incomplete References (to uncomplete or partly-defined beans) are significantly different to existing References in Spring usage. Any derivation code or active logic on a setter method in Bean B, is likely to break if Bean A has not actually had its properties init'd yet.

Having said that, it would be rather nice to allow such circular/ graph dependencies to be constructed from Spring. Thanks for this work, Keith! For safety's sake however it would be preferable that the REF or (less accurately) the BEAN be explicitly specified as an Incomplete Reference.


A few thoughts:
- We could say EARLY-REF="BeanA" in the XML
  - But we've already got quite a few different REF attributes in various tags... so this would multiply DTD complexity.
- We could say REF="BeanA; early" in the XML.
  - Or perhaps something like REF="early: BeanA".

I think I like the REF="early: BeanA" format best.

Less useful possibilities:
- Saying <BEAN ID="BeanA" EARLY-REF="true"> would loosen all reference links, undesirably;
  - Rather than just 'lossening' the ones we need to loosen.
- Saying REF="late: BeanB" or PROPERTY LATE could mean 'set this property after all the others';
  - Which would fairly much suck for being excessively heavy and giving less control.


Juergen, Keith, your thoughts ?

Cheers,
T

Keith Garry Boyce added a comment - 03/Feb/06 02:20 PM
I don't understand what you're driving at? Can you provide an example how you think the implementation is broke?

Thomas Whitmore added a comment - 14/Feb/06 07:21 PM
Hi Keith, my comment was thinking of Bidirectional Links/ Circular References in the object graph. The post may actually be more relevant to Beans XML and the bean factory, but some of the same issues may apply ?