Spring / GWT Software Architecture for scalable applications – Part 1

During this article I’m willing to share with you a clean software architecture to build high scalable enterprise application based upon GWT (on the front end) and Spring (on the back end).

I’m going to start by showing the overall software architecture and describing all technologies and best practices I use, then on the next articles we will build a little application from scratch step by step, on each article we are going to concentrate on a precise part of the solution.

GWT/Spring Software architecture

The solution is composed from tow parts, the client side (GWT) and the server side (Spring/JEE).

Client side (GWT)

On GWT I use the MVP design pattern along with activities, and RequestFactory. On this solution the MVP is just an abstraction and it is implemented using activities, the presenter and RequestFactory.

On the table below I describe each letter of MVP and how is implemented in the solution :

On this architecture the objects creation and injection (this include views, remote interfaces, event bus…) is managed by an IoC framework (like Spring) called GIN and is based upon Google Guice. I’ll show you on the next article how to configure it and how I use it on this approach.

View is a singleton configured using GIN (GWT IoC framework), most of the time a view is used by just one activity.

Presenter is an interface implemented by a given view, to give a lightweight object which will be manipulated later by the activity to interact with the view.

Activity It contains no Widgets or UI code and have a lifecycle. All the code about the UI business logic is written here. Activities manipulate both the view (by the intermediate of the presenter) and models (by calling the RequestFactory) and are started and stopped by an ActivityManager that is associated with a container Widget (a certain display area on the screen).

Event Bus is a singleton configured using GIN and can be injected on activities and views, its function is to dispatch events to interested parties. An event bus eases decoupling by allowing objects to interact without having direct dependencies upon one another.

RequestFactory is a factory exposing all your RequestContext. Each spring service you want to expose to the client must have its clone interface on GWT which extends the interface RequestContext.

Proxy are the clones of the objects (business objects or VO’s) used on the spring services in the server side they are manipulated by the remotes interfaces (interfaces which extends RequestContext), activities and views on GWT.

Server side (Spring/JEE)

On the server side I use a simple service oriented architecture composed from DAO (data access object managed by Spring Data for JPA), services (transactional and secured service layer exposed to GWT through the RequestFactory API), and finally persistent entities or value objects (theses are manipulated by services and DAO).

Spring services : Here we have all the functionality that our server side expose to the client. In order to manipulate data a service is composed from one or many DAO’s, also all the methods of the service must be transactional (so we can rollback if there is an accident) and secure.

Project structure

Now that we know some foundations about the solution, I’m going to show you how is the project structured :

The project is divided in tow big packages, the server side and client side.

Structure of the server side

On the server side we have the following sub packages :

repos: composed from tow other packages ‘simple’ which contain spring data DAO’s interfaces and ‘advanced’ which contain advanced DAO’s (this type of DAO’s uses the EntityManager and they perform some business logic on data).

services: here we found the interfaces and implementation of services exposed to GWT client.

rest: here we put REST controller to expose a REST API to build for example native iOS or Android application.

security: all classes related with security like authentication service, security filters… (I use spring security to manage the security of the application).

Structure of the client side

On the client side we have the following sub packages :

activity: holds all activities, in each activity there is an inner interfaces which is the presenter implemented by the view.

place: here we find the places, a place is used by the ActivityManaged defined for each display region on the GWT shell (or layout) to decided which activity to load. I’m going to talk about places on the following articles.

UI: holds all the declarative XML files or java code to describe the UI (UI Binder). I also put in here the application layout (I called the shell). Every other files except layout related files are grouped on sub packages each one contain the UI’s that concern a certain module of the application.

event: contain all the custom event we use on the EventBus. The event on here are used for example to update the content of a view when we receive some data, when another display managed by another activity trigger an event. Check this article http://goo.gl/VpJM to learn more about how to use events on a MVP architecture.

request: here we find RequestContext interfaces in relation with Spring services on the back end, the communication is done using a RequestFactory servlet, for more information about how to integrate Spring and GWT check the following article http://goo.gl/iL0yv. The sub package proxy holds the value object exchanged between the client GWT and server Spring, they are a representation of the remote objects (entities or VO’s) managed by Spring on the client side.

ioc: holds infrastructure code to set up the IoC container on the client (configuration for GIN). The ‘MyAppModule’ file configure the beans managed by GIN container and theirs scope (Singleton, Provider…) this file is like the applicationContext.xml on Spring. The ‘MyAppInjector’ indicate which of the defined beans we want to get to explicitly (anywhere even if it is not a GIN bean) it is like a factory of beans. A given application can have multiples ‘Modules’ and ‘Injectors’ files.

resource: here we host the custom style files and images, I use heavily the ClientBundle GWT API to learn more check http://goo.gl/BofQO.

That’s it for this article, on the following article I’ll describe the example we are going to build step by step using this architecture.

18 Responses

I worked on a Spring/GWT project three years ago, and I have this advice; use Load-Time Weaving to introduce GWT interfaces like RemoteService into the Spring services. It is a mistake to have the Spring back-end depend on the GWT jars

I agree with you because for the server (Spring) to communicate with the client I need to configure a RequestFactory servlet on the back end, which is fine in my case because the client code and server code are on the same project so they share the same libraries.

Can you give an example or a link about your method, I’m really interested on how you achieved this.

I’m sorry, butthat project is dead, and I’m somewhere else not. But I was trying to avoid having my Spring FooService implement GWT’s RemoteService. Pure Spring AOP didn’t help (at least then) because @DeclareParent required a specific implementation of the RemoteService interface; I couldn’t tell it that FooService implemented RemoteService as is. But I set up Load-Time Weaving and in the webapp, My FooService got to adopt RemoteService so GWT could reach it.

In general, you want your Spring code in a different project from your GWT code. After all, who says that every thing you use it for will involve GWT, or even a UI? What happens if you’re asked to expose your back end in a web service? You’ll be embarrassed if you need the gwt jars just to run the web service.

On the architecture I described, the Spring services don’t implement or extend any GWT stuff they are simple plain POJO and can be reused for example by REST controller later.

I can easily separate the GWT and Spring projects, and the RequestFactory Servlet is just one special Layer from many other layers to communicate with GWT clients, even GWT 2.4 contain a special jar called “requestfactory-server.jar” which hold just classes for the RequestFactory Servlet, so you don’t have to put on your server all the GWT api just to use the special servlet.

Very good article @imrabti. Do you see any value addition on reusing the DTO used at Server Side as VO in GWT (Client Side), we’ve got a big issue in duplicating them and packagin them as a separate client module so as, the GWT makrks them as GWT Serilizable object.What approach you took?

The Use of DTO in my solution is part of the RequestFactory API, their goal is to map the Objects On the Server (which in case are Entities) to The objects on Client (GWT client), Because this is a distributed architecture and the Client and Back can be deployed on different servers (Client is just static pages => deployed on Apache HTTP, Back end JEE application use of Tomcat or other JEE servers). It is not the plain classic VO and also it is not a duplication for more informations check this URL to see what I’m talking about : http://goo.gl/yi3u7.

The RequestFactory is the newest way to integrate GWT with a JEE back-end and it’s like and enhanced version of GWT-RPC with more features, I encourage you to take a look at it.

Great post. Just one question. Do you really think the views should be using the event bus directly? Views are suppose to be “dumb” so a big part of me thinks that they shouldn’t have access to the eventbus. At the same time, I think it’s okay for the views to be UI smart.. so for example having a text box widget that handles dom events.. but we don’t need the eventbus for anything like that. The eventbus is only used to coordinate APPLICATION events as opposed to UI events.. so in that sense shouldn’t all of that be handled by the activity? None of our views contain references to the eventbus. I’d love to hear your thoughts..

Yes I totally agree, the view should deal just with UI logic and there for all of the Business logic need to be handled on the Activity. Normally the event bus shouldn’t be injected on the view, but In my application I had a complex views (multiple activity manager, each one with its own view) that need to interact with each others (No business logic just UI stuff) and the only clean way to do this is by using the event bus.