Wednesday, May 4, 2011

Scope strategies: Spring and Guice

Last year, we used Guice in order to implement an Android solution for LeapFactor. It was my first Guice project, so I didn't had experience with the framework. On the other hand, I have had experience on many projects using Spring.

A crucial difference is the default scope: Spring beans by default are singleton, while Guice beans are prototype. I realized this when a server-communcation service (which at that moment contained session state) started losing connection.

My first approach was annotating the communication service as singleton. But when I tried to inject prototype beans inside such singletonGuice refused to do it claming that there were a problem with scopes. I was forced to creating a new bean, just to hold the session state.

I though: cool, the framework (Guice ) helped me in order to improve the design. If I were using Spring, the container would have injected such bean (which would be an error, since just the first instantiated prototype woudl be injected).

A few months ago, we started developing a framework for using in Oxen internal projects. It is based on OSGi and Spring DM. I created an agnostic OSGi service which handled the session state data and I wanted to create a custom scope in order to store Spring beans into such session.

Researching a little about custom scopes I found a cool feature, which  uses a completely different approach than Guice. The scoped-proxy tag. For example, you can write (importing the appropiate namespaces):

<bean id="userPreferences" class="com.foo.UserPreferences" scope="session">
   <aop:scoped-proxy/>
</bean>

which creates a proxy for the bean that delegates onto different beans, according to the subjacent scope.

This is pretty cool. For example, yo can inject a bean stored in the HTTP session into a singleton bean and treat the non-singleton bean as it were a singleton. The proxy will be responsible for locating the real bean in the HTTP session.

Both strategies seems good to me. I think that Guice approach imposes some (good) restrictions on the design, while Spring approach gives you more flexibility.

2 comments:

  1. In Guice, you should inject a Provider into ClassA if the lifecycle of ClassA is longer than of DependencyA. When you do so, you invoke the 'get' method to get object in on-going scope.
    In CDI, on the other hand, you just inject DependencyA into ClassA and it is, by default, covered by a proxy, so the proxy itself asks the container for the instance in the currently going scope.

    Regards,
    Witold Szczerba

    ReplyDelete
  2. So, CDI approach is more similar to Spring?

    ReplyDelete