What we are going to create is a revision of Spring MVC Template Project that instead of setting up project using XMLs, is configured using Java classes. The new directory structure is:

If you look carefully, under src/main/webapp directory, there are no XMLSpring configuration files. And no web.xml, but I will talk about that later. For now imagine that under WEB-INF there is a web.xml file.

See that structure is very similar to previous one, but spring directory is removed and config package is created. Moreover XML files have been converted to standard classes.

Again ignore strange WebAppInitializer class that has appeared. Let's see applied changes:

root-context.xml has its equivalent with mytld.mycompany.myapp.config.RootContextConfig.

Most important thing in previous class is @Configuration annotation. This annotation indicates that the class can be used by the Spring IoC container as a source of bean definitions.

Class that replaces servlet-context.xml file is:

I am going to show you servlet-context.xml content so you can ensure that XML and Class contain the same parameters.

Apart from @Configuration annotation, this class is annotated with @EnableWebMvc, which enables @Controller programming model, and @Import for importing other bean definitions, like servlet-context.xml imports controllers.xml. This class extends from WebMvcConfigurerAdapter because some extra configuration is required. WebMvcConfigurerAdapter defines options for customizing or adding to the default Spring MVC configuration. In summary it provides customizing parameters as mvc namespace does. In our case, as servlet-context does, we define static resources path to /resources/, so we only override configureResourceHandling method. If for example we would like to register interceptors, configureInteceptors method should be overridden. And finally @Bean is used for creating the view resolver bean. @Bean methods define instantiation, configuration, and initialization logic for objects to be managed by the Spring IoC container.

Next class is called ControllerConfig and is the responsible of registering controllers. In this case @Bean approach is used because component-scan is not supported directly. Anyway you can use scan method of AnnotationConfigApplicationContext for same purpose but in this case first choice has been chosen.

And finally web.xml must be changed for loading Java-based configuration instead of XML-based ones. In this case contextClass parameter of DispatcherServlet and ContextLoader listener must be changed to AnnotationConfigWebApplicationContext so Spring IoC Container can load beans from configuration classes, and contextConfigLocation must be pointing to configuration classes, and not XML files.

And I suppose you are wondering why in previous directory structure cannot be seen web.xml but WebAppInitializer class. This is explained in my post, and is another new feature of Spring 3.1 M2, that you can configure a Spring Web MVC application with no web.xml.

So if you want a 100% Java-based configuration, simply removes web.xml file and creates the WebAppInitializer class, which looks like:

As you can see, same elements of web.xml are present but they are configured in a programmatic way.

Hope you find the post useful, of course you can create hybrid applications, mixing elements configured in XML way and other ones configured in Java classes.

Two Spring Template Projects are provided, one configuring Spring MVC application in a Java-based fashion and web.xml, and another one 100% Java-based configured.

5
comentarios:

Nice post, Alex! Just one suggestion: I would recommend naming your "Controller" @Configuration class "ControllerConfig" or something similar. This will help avoid confusion with Spring's own @Controller annotation, and it's probably a good idea in general to use a "Config" or "Configuration" suffix to clarify the purpose of @Configuration classes.