In this example we build a spring based XML free web application. That’s right, no XML.
Why would you want an XML free web application? No reason. It just sounds cool. Although if you do it that way a couple of times, you can’t go back to XML. You wouldnt want to. probably…
Step 1
This examples needs a Servlet 3 container. When you think of a web application, the first thing that comes to your mind is web.xml. That’s where you configure your servlets and your mappings. We dont have web.xml with us anymore. Its abandoned us (or we have abandoned it). But despair not! You still have a friend in the
WebApplicationInitializer
. Note that in this example we would be using spring classes. This is also a spring class and its purpose is to Initialize the web application.
There is still something missing, isn’t it? I mean how does the container know that i have a class that implements this interface.
Well, it just does. The Servlet 3 container was designed in a way such that if you write up a class that implements the WebApplicationInitializer (actually that’s the spring version of ServletContainerInitializer), the container would load it first and then depend upon it to provide the web application configuration. So there you are… You create a new web project in eclipse (or any other IDE of your choice or if you are not lazy like most of us, you use a plain text editor), and in the project create a java class that implements the WebApplicationInitializer.
We implement the onStartup method, which is called when the web application starts. This is where the ServletContext is configured with servlets, filters, context-params etc. In our example we first create the AnnotationConfigWebApplicationContext. This allows the application to read classes that have been annotated with the Spring @Component or @Configuration. We tell this class that our Spring config classes are in the com.studytrails.quiz.config package. We will look at the Spring config classes later on. We then register the Spring DispatcherServlet and map it to the ‘/’ path.
Step 2
Lets look at the Spring config classes now. So far we have a web application that is initialized by the ApplicationInitializer and where we have registered the Spring dispatcher servlet and also told the container where the other config classes are
Here’s our first Config class
We call it the WebConfig class because here we configure the web related stuff in Spring (as opposed to the data related stuff like the datasource). Here’s an explanation of the important classes or annotation.
- WebMvcConfigurerAdapter – This class need to be extended to provide a callback for the container to provide Spring MVC related configuration. Any class annotated with @EnableWebMvc can extend this class (in affect, implement the WebMvcConfigurer) interface. The adapter provides points specific touch points where configuration can be added. Some of the methods that can be overriden are addFormatters, addArgumentResolvers, addResourceHandlers etc. In our example we implement the configureViewResolvers where we add the default Spring JSP View Resolver. ViewResolverRegistry is a helper class that helps in configuring a chain of ViewResolver instances.
- @EnableWebMvc – When this annotation is added to a @configuration class, it adds Spring MVC based configuration defined in WebMvcConfigurationSupport class. What configuration does it really add? It adds HandlerMappings (RequestMappingHandlerMapping, BeanNameUrlHandlerMapping etc), HandlerAdapters (RequestMappingHandlerAdapter, HttpRequestHandlerAdapter etc), ExceptionResolvers, AntPathMatchers and so on. For a full list look at the class documentation (very smart eh!)
- @Configuration – This declares that the class declares methods for bean management. The Spring container processes this class and creates beans definitions defined in this class.
- @ComponentScan – Tells the Spring container to scan the directory specified for components. In our example we want it to scan the controller directory because that is we have defined the controllers (which we will see later). In a typical XML based configuration we would define the beans in the xml, but here Spring does not know which classes have been annotated as beans so this is where we inform the Spring container.
Step 3
We defined the Web config class above, lets now define the Data config class.
This class is also annotated with @Configuration and @Component. This class guides the scanning of the DAO and service directory for bean definitions. we could have specified the scanning of the service directory in the web Config class. This class also defines the dataSource bean. In a real application we would separate out the properties in a properties file. We introduce one more annotation here: @Bean
- @Bean – This annotation tells that the method produces a bean that will be managed by the Spring container. The name of the bean may be taken from the method name or can be explicitly specified using the name attribute. If a class as more than one bean annotated methods then one method can directly use the other bean by using the other bean’s method.
Step 4
So far, we have Initialized the application and have added the jsp view resolver and a data source. Lets write our DAO
This class defines a method that gets a list of question from the database. The implementation is for demonstration only, the actual database structure can get quite complex. The DAO extends JdbcDaoSupport. We have three new annotations here. Lets look at them (XML-free is all about annotations!)
- @Repository – This doesn’t really do much except tell that the class contains methods to manipulate domain driven Objects. It has some advanced uses such as making it eligible for spring DataAccessException. In our case we have added it because we can use this annotation in place of the standard @Component annotation because it helps us recognize the class as being responsible for Data Access. The annotation is just a specialization of the @Component annotation.
- @Autowired – We created the dataSource bean earlier in the DataConfig class. We inject the bean in the DAO using the AutoWired annotation. The bean is injected immediately after the class creation and before any bean lifecycle methods are called.
- @PostConstruct – The method annotated with this annotation is called after dependency injection is complete. Only one method in a class can be annotated with this annotation. the method does not take any parameter except in EJB’s. The return type must be void. Method must not throw a checked exception.
Step 5
Lets create the service. The service calls the method defined in the DAO.
We use the @Service annotation which says that the class is a Service. It is a specialization of the @Component annotation. The DAO is injected into the service using the autowired annotation.
Step 6
The last part of the puzzle. The controller is what intercepts the request. It has RequestMappings that map a request to a method or a class. This is similar to the XML where we specified the Request Mapping.
The controller maps the request from http://www.mydomain.com/{topic}/{subtype} to the getQuizQuestions method. The method uses the service to get quiz questions using an id formed from the topic and subtype and sets it in the session. Lets look at the annotations introduced in this class. The {topic} or {subtype} can be any string.
- @Controller – This tells that the class is a controller. Its a specialization of @Component.
- @RequestMapping – This maps a request to a specific class or method. In our example we map the /topic/subtype to the getQuizQuestions method. so both “/frameworks/spring” and “/java/java8” would map to this method.
- @PathVariable – This annotation binds a method parameter to the URI template. In our example subtype parameter contains the string passed in the URI /{topic}/{subtype}
- Model – This model is available to the view and can be enriched from the method. parameter.
That’s it. This was the last step. This tutorial should have armed you enough to plunge into an XML free development environment. If you have any questions, please feel free to mail us or drop in your comments. Follow us