I'm refactoring a GWT app and plumbing in Guice to remove some of the cruft thats developing in our web开发者_开发百科.xml. I'm using guice to map the RPC services called by GWT client code. Roughly following the approach outlined here. http://stuffthathappens.com/blog/2009/09/14/guice-with-gwt/
This approach requires moving away from extending RemoteServiceServlet but also means I no longer get access to the init(), shutdown() and destroy() methods that would normally be available via the ServletApi.
This is not a problem for most of the services we've developed but in one case I've stumbled across a snippet of code in our service that relies on using init() to Create an object that passes in a reference to the servlet and kick off a thread that calls a method on the servlet class that polls a service and maintains a cache that can be used by the GWT service. Please see code below ( shortened for clarity )
public class MyServiceImpl extends RemoteServiceServlet implements MyService{
private CacheRefresh cr = null;
public void init(ServletConfig servletConfig){
super.init(servletConfig);
cr = new CachRefresh(servletContext, this) ;
cr.start();
}
public String someMethod(){ .. }
}
public class CacheRefresh extends Thread{
public CacheRefresh(ServletContext context, MyServiceImpl servlet){
...
}
public void run(){
context.setAttribute("A_MAP_KEY", servlet.someMethod() )
}
}
I appreciate that using Threads in this way is also probably not a good idea. This is code I've inherited and I'll get round to doing something better there in due course.
Does anyone have any good ideas on how to resolve this? The only option I can think of at the momen is to leave it is and configured by the mapping in the web.xml file. I don't like the idea of having configuration in loads of places and scattered around like pixy dust.
Any suggestions welcome.
Edit - We are using Guice 2.0
This is an old thread, but for posterity's sake, a similar question contains the answer I think you're looking for: GWT RPC GWTTestCase + GUICE 2.0
Namely (taken mostly from Will's answer in the above question), where you configure your ServletModule
, you add:
serve("/myapp/yourservice").with(YourServiceImpl.class);
And then leave your GWT-RPC class almost as is, except for adding a few Guice annotations:
@Singleton
public class YourServiceImpl extends RemoteServiceServlet implements YourService {
private Provider<SimpleDao> daoProvider;
private OtherGuiceManagedObj obj;
@Inject
public YourServiceImpl(Provider<SimpleDao> daoProvider, OtherGuiceManagedObj obj) {
this.daoProvider = daoProvider;
this.obj = obj;
}
// ... RPC method implementations
}
However, you still need to duplicate the service path with the @RemoteServiceRelativePath
annotation on your service interface declaration, but this is no worse than with web.xml
. (You could probably write something to scan certain paths for service interfaces annotated with @RemoteServiceRelativePath
and add the Guice servlet serve().with()
calls at startup time, but maybe not worth the trouble.)
@RemoteServiceRelativePath("yourservice")
public interface YourService extends RemoteService {
// ...
}
I've done this before and it works as expected, Guice-injected and all.
精彩评论