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