RequestFactory, ServiceLocator and Spring

981 views
Skip to first unread message

d95sld95

unread,
Dec 14, 2010, 3:46:38 PM12/14/10
to Google Web Toolkit
I am trying to find a good solution to integrate the RequestFactory
with Spring. I implemented this ServiceLocator (no exception handling
included for simplicity):

public class SpringServiceLocator implements ServiceLocator {

@Override
public Object getInstance(Class<?> clazz) {
HttpServletRequest request =
RequestFactoryServlet.getThreadLocalRequest();
ApplicationContext context =
WebApplicationContextUtils.getWebApplicationContext(request.getSession().getServletContext());
return context.getBean(clazz);
}
}

I annotate my RequestContext with the GWT @Service annotation (not the
Spring one). Example below:

@Service(locator = SpringServiceLocator.class, value =
AddressService.class)
public interface AddressRequest extends RequestContext {
// Get address by id
Request<AddressProxy> get(Long id);
}

When I fire the Address request using RequestFactory, the
SpringServiceLocator locates the AddressServiceImpl.class and returns
an instance. The method "public Address get(Long id)" is called and
returns a new instance of an Address object.

So it works... but is there a better way? Is the lookup in
getInstance() to slow, could anything be cached, etc. Any input is
welcome.

zixzigma

unread,
Dec 15, 2010, 2:16:54 AM12/15/10
to Google Web Toolkit
I would also like to hear about the best practice to use
RequestFactory with Spring.

Thomas Broyer

unread,
Dec 15, 2010, 6:47:48 AM12/15/10
to google-we...@googlegroups.com
RequestFactory will actually cache them (see the ServiceLayerCache class, both the ServiceLocator instance, associated with a given RequestContext class, and the service instance, associated with a given method, are cached, using memoization).

Zigu

unread,
Dec 16, 2010, 1:40:28 AM12/16/10
to Google Web Toolkit
Your solution looks great. But I'd like to add that it only works with
version GWT 2.1.1 or higher. With this version they introduced the
service layer API for Requestfactory.

Additionally, I'd like to ask is whether it is useful to make the
ServiceLocator ApplicationContextAware? For example:

public class SpringServiceLocator implements ServiceLocator,
ApplicationContextAware {
private ApplicationContext _applicationContext;

@Override
public void setApplicationContext(ApplicationContext
applicationContext) {
_applicationContext = applicationContext;
}

@Override
public Object getInstance(Class<?> clazz) {
return _applicationContext.getBean(clazz);
}
}

d95sld95

unread,
Dec 16, 2010, 12:06:17 PM12/16/10
to Google Web Toolkit

ApplicationContextAware only works if the SpringServiceLocator object
was managed by Spring. In this case the RequestFactoryServlet is
responsible for creating the SpringServiceLocator and the
setApplicationContext method won't be called.

zixzigma

unread,
Dec 19, 2010, 3:15:01 AM12/19/10
to Google Web Toolkit
I do NOT think we need these chains of method calls to get hold of
ApplicationContext

> ApplicationContext context =
> WebApplicationContextUtils.getWebApplicationContext(request.getSession().getServletContext());


if all we need in the end is "a reference" to the ApplicationContext,
why not inject it ?

@Autowired
ApplicationContext context;

and in the method, just one line:

> return context.getBean(clazz);


the complete code:

public class SpringServiceLocator implements ServiceLocator {

@Autowired
ApplicationContext context;

@Override
public Object getInstance(Class<?> clazz) {
return context.getBean(clazz);
}


I believe, there is only ONE ApplicationContext for the entire
lifetime of application.
therefore no matter what user/session makes a request, the application
context will be the same.
HttpRequest and Session, won't give us any more detail that we can't
otherwise obtain.
ApplicationContext becomes available on startup, we don't need all
those calls to get hold of it.

to summarize, that chain of method calls (getting hold of HttpRequest
and Session, and use of WebApplicationContextUtils)
can be all together avoided, and replaced by injecting
ApplicationContext directly.

what do you all think of this ?
isn't this what dependency injection is about ?

Thomas Broyer

unread,
Dec 19, 2010, 4:10:55 AM12/19/10
to google-we...@googlegroups.com
Isn't @Autowired subject to the same limitations as highlighted by d95sld95?

(note however that you can use a ServiceLayerDecorator to instantiate the service locator, and you can then have dependency injection working all the way town to it; that's what I'm doing with Guice).

steen laursen

unread,
Dec 19, 2010, 2:00:29 PM12/19/10
to google-we...@googlegroups.com

I will have to take a look at the ServiceLayerDecorator to see how that would work with Spring. Maybe that's is a better solution?

Any the @AutoWired annotation wont work since the ServiceLocator and RequestFactoryServlet is not managed by Spring (ie Spring did not create the objects, the servlet container did).

zixzigma

unread,
Dec 19, 2010, 3:27:48 PM12/19/10
to Google Web Toolkit

> Any the @AutoWired annotation wont work since the ServiceLocator and
> RequestFactoryServlet is not managed by Spring (ie Spring did not create the
> objects, the servlet container did).

1- can we register ServiceLocator and RequestFactoryServlet with
Spring's ApplicationContext ?
so that upon application startup, Spring's application context,
bootstraps and creates them ?

2- What happens to Spring's Dispatcher Servlet:
org.springframework.web.servlet.DispatcherServlet ?

I think we need to tell DispatcherServlet to redirect all gwt requests
to RequestFactoryServlet.
(implement it as a Filter ?)

zixzigma

unread,
Dec 19, 2010, 5:04:58 PM12/19/10
to Google Web Toolkit
I came up with this, based on your suggestion.
I am not sure if this is correct though.


public class SpringServiceLocator implements ServiceLocator {

@Autowired
private ApplicationContext context;

@Autowired
private ServiceLayerDecorator serviceLayerDecorator;

@Override
public Object getInstance(Class<?> clazz) {

return
context.getBean(serviceLayerDecorator.resolveDomainClass(clazz));

}
}

dan l

unread,
May 17, 2011, 5:03:27 PM5/17/11
to google-we...@googlegroups.com
i know this is an old thread, but i thought i should leave my thoughts somewhere.
i was having problems with @Inject or @Autowired not working because of who is managing the servlet. 

my friend took a look at your previous posts and whipped this up and it seems to be working great:

public class MyServiceLocator implements ServiceLocator {
public Object getInstance(Class<?> clazz) {
HttpServletRequest request = RequestFactoryServlet.getThreadLocalRequest();
ApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(request.getSession().getServletContext());

//we should probably check class for null and return something the client can deal with
// just in case 
        return context.getBean(clazz);
  
 }
}

and so far its working with two services pretty well. i dont know a whole lot about spring or gwt requestfactory but i thought this might be helpful to someone 

Tom

unread,
Sep 28, 2011, 4:12:48 PM9/28/11
to google-we...@googlegroups.com
Works great thanks for sharing!!
Reply all
Reply to author
Forward
0 new messages