Monday, July 9, 2012

Guice a bit more convenient than Spring in injecting circular dependencies in session beans

It is not very easy to find, but Spring does not support circular dependencies for scopes other than Singleton (default scope for Spring). That may be very frustrating. There are some workarounds, but since I met this limitation right at the very beginning of the project, I just moved to Guice, that supports session scoped beans with circular references out-of-the-box.

If you want to try it yourself, or try some workarounds for Spring - I have created a small simple github project as an illustration.

EDIT: Actually now there is an easy workaround to this intentional Spring behavior. You may use javax.inject.Provider of session-scoped beans inside other session-scoped beans and introduce circular dependencies. This will not work in Spring 3.1.0-3.1.2 due to a regression, but this bug is fixed in 3.1.3 Spring. I have updated the example. For session-scoped beans this workaround is really very easy since you may call provider.get() any number of times in one session and you will always recieve one and the same bean. This may be a bit trickier with prototype-scoped beans or any custom scope but this idea may in some form apply to them too.

So Spring is not really owned and now allow you to do the same thing. But still you need to remember that Spring guys do not like circular dependencies in beans and they have reasons for that.

Thrift exposed via webapp servlet

Thrift services can be exposed via servlets. Now the TServlet class is part of the core thrift package in java. It is relatively easy to use, but there are some nuances.

First - it requires some Processor and Protocol to be used. Example of such usage maybe found here. Though it is about OSGI Servlets, not web applications - this example is easy and small. However it is stated there that due to violation of Servlet specification (no default constructor) it is not possible to use this servlet in web application. Actually it can be used.

  • We can either use it directly with some covering code, like in this stackoverflow answer.
  • We can use any standard way of delegating servlets like Spring, or Guice and maybe some other frameworks that most likely are already used in your application.
I have created some small test project to illustrate these options (hand-written delegating code, Spring and Guice) and placed it on github. Maybe it will be useful to someone except me ;-)