Thursday, October 1, 2009

GWT server-side integration with Spring (@Autowired)

Old Approach:
Previously we use to load the application's Spring configuration files manually using a custom class (SpringLoader) that was a wrapper around the Spring's ClassPathXmlApplicationContext class. Seemed like an easy way to do things at the time.

All the GWT server-side services would manually look up their required Spring beans which provided the back-end/server tier functionality.
For example:
public class GwtSecurityServiceImpl extends RemoteServiceServlet implements GwtSecurityService {

  /** The service used to check user's access rights and to load user menus. */
  private UserSecurityService userSecurityService = (UserSecurityService) SpringLoader.getBean(SpringBeanId.SECURITY_SERVICE_ID);

public CatchSystemMenu isValidUser(String username, String catchSystem) 
  throws CatchSystemsGwtException {
  ...
  Boolean validUser = userSecurityService.isValidUser(username, catchSystem);
  ...
}


Better Approach:
Use the usual Spring's context listener (defined in the application's web.xml) to load the application's Spring context on application start on.
<context-param>
  <param-name>contextConfigLocation</param-name>
  <param-value>classpath:myapp-spring.xml</param-value>
</context-param>
<listener>
  <listener-class>
  org.springframework.web.context.ContextLoaderListener
  </listener-class>
</listener>

Define a base class for all the GWT service classes to extend. This class provides the injection of the Spring managed attributes, using Spring's functionality.

Base GWT service class:
public class SpringRemoteServiceImpl extends RemoteServiceServlet {

  private static final long serialVersionUID = 1L;

  @Override
  public void init() throws ServletException {
    super.init();
    setSpringServices();
  }

  private void setSpringServices() {
    WebApplicationContext ctx = WebApplicationContextUtils.getRequiredWebApplicationContext(getServletContext());
    AutowireCapableBeanFactory beanFactory = ctx.getAutowireCapableBeanFactory();
    beanFactory.autowireBean(this);
  }
}

The individual GWT service classes just extend this class and use the usual Spring @Autowired annotation to inject their Spring-managed attributes.
public class GwtSecurityServiceImpl extends SpringRemoteServiceImpl implements GwtSecurityService {

 /** The service used to check user's access rights and to load user menus. */
 @Autowired
 private UserSecurityService userSecurityService;

 public CatchSystemMenu isValidUser(String username, String catchSystem) 
   throws CatchSystemsGwtException {
 ...
 Boolean validUser = userSecurityService.isValidUser(username, catchSystem);
 ...
 }
}

Nice and easy.
Have a banana.

No comments:

Post a Comment