That's a decent approach. As you say, you _have_ to make sure your beans are marked as non-singleton (prototype) scope. Otherwise, you've got threading problems.

The (tiny) problem with your approach is that you are tightly coupling your SpringFinder with the Spring library. Well, duh right? Ya, this isn't too much a problem for most people. However, it is a problem if you decide to use another IoC framework at some point. Spring would be _ideally_ configured without any in-class dependencies. But, obviously that's just the pie-in-the-sky ideal.

I like injecting the necessary properties into the Finder class itself, and then my createResource class creates simple little connector classes to the appropriate spring beans. For one, this saves the Spring dependency.

This approach is also nice because it saves the Spring container from having to continually generate the more "heavy" middle-tier classes (like services, daos, etc.). With this approach, the heavy stuff is still a singleton spring bean, and the Finder still gets to create small little Resource classes like it wants to.

With your approach, however, you end up having to continually create your inner spring beans per request. Maybe this scales, maybe it doesn't, but it's something at least to keep in mind.

I guess generally that's why I like my spring managed beans to stay singletons and using a small "wrapper" that converts the normally stateful Resource into a stateless request into the singleton.

Adam


Justin Makeig wrote:
Tom, thanks for your additional input into Restlet/Spring integration. I too am looking for "the" solution.

So far, I take a slightly different approach and use Spring's ApplicationContext as my Resource factory.

I've created SpringApplicationContext as an extension of com.noelios.restlet.application.ApplicationContext and expose the Spring ApplicationContext as a property. I extended Finder as SpringFinder. Its createResource method looks as such:

@Override
public Resource createResource(final Request request, final Response response) { ApplicationContext springContext = ((SpringApplicationContext) this.getContext()).getSpringApplicationContext(); Resource resource = (Resource) BeanFactoryUtils.beanOfType(springContext, getTargetClass());
    resource.init(getContext(), request, response);
    return resource;
}

I get the Spring ApplicationContext from the Finder's (Restlet) context and then look for a resource bean there by type. So essentially, my Spring ApplicationContext is my resource factory. For example,

<bean id="userResource" class="net.troove.ui.restlet.UserResource" singleton="false">
    <property name="userDao" ref="userDao"/>
    <!-- Other collaborators here -->
</bean>
<bean id="userDao" class="net.troove.test.SimpleUserDao" singleton="true" />

where net.troove.ui.restlet.UserResource extends org.restlet.resource.Resource.

Because resources are request-scoped, you have to make sure they declare singleton="false".

Comments/criticism would be much appreciated.

Justin

Reply via email to