Project

General

Profile

cdmlib-remote-webapp configuration and bootstrapping

This page describes how spring mvc in cdmlib-remote-webapp is configured and whow the application is being bootstrapped based on this configuration.

Bootstrap

The bootstraping startst with the web.xml file in which the main application context and the DispatcherServlet context configured to be picked up by the application container.

In a Spring MVC web application you will typically have a root WebApplicationContext loaded via Spring's ContextLoaderListener and a child WebApplicationContext loaded via Spring's DispatcherServlet. This results in a parent-child context hierarchy where shared components and infrastructure configuration are declared in the root context and consumed in the child context by web-specific components.

Spring has support for hierarchical bean factories, so in the case of the spring mvc, the dispatcher servlet context is a child of the main application context:

If the servlet context was asked for a bean called "abc" it will look in the servlet context first, if it does not find it there it will look in the parent context, which is the application context.

For very detailed explanation on this topic, see http://stackoverflow.com/questions/15818047/spring-namespace-vs-contextconfiglocation-init-parameters-in-web-xml#answer-15825207

DispatcherServlet context

The DispatcherServlet builds the MVC context, handles all HTTP requests and delegates them to other components of the MVC architecture.

The configuration file for this context is the /WEB-INF/cdmlib-remote-servlet.xml

main application context

The main application context the the context in which the core cdm application with model, persistence and services is initialized.

The configuration file for this context is the /WEB-INF/applicationContext.xml

Java Spring configuration classes & packages

The CDM-Library has a couple of packages in which Java Spring configuration classes are located:

eu.etaxonomy.cdm.api.config

The package eu.etaxonomy.cdm.api.config contains spring configurations
which are loaded automatically into the root application context.
These classes are injected into the context via component scan.

Found in:

  • cdmlib/cdmlib-services

eu.etaxonomy.cdm.opt.config

The package eu.etaxonomy.cdm.opt.config contains spring configurations
which can be loaded into the root WebApplicationContext loaded via
Spring's ContextLoaderListener, but which are optional.

This package must not be covered by a component scan the bean in here should be added
individually to the context
.

Found in:

  • cdmlib/cdmlib-remote

eu.etaxonomy.cdm.remote.config

The package eu.etaxonomy.cdm.remote.config contains spring configurations
which are to be loaded into the child WebApplicationContext loaded via
Spring's DispatcherServlet. These classes are injected into the context via component scan.

Found in:

  • cdmlib/cdmlib-remote-webapp
  • cdmlib-remote

eu.etaxonomy.cdm.addon.config

The package eu.etaxonomy.cdm.addon.config is an extension point where
addon-modules can place their Spring configuration classes so that the addon
can be bootstrapped. A component scan defined in cdmlib-remote-webapp will
find them.

Found in:

  • cdmlib/cdmlib-remote-webapp
  • cdm-vaadin

Participating classes and configuration files

web.xml

The file /cdmlib-remote-webapp/src/main/webapp/WEB-INF/web.xml contains an listener entry and the configuration of the Spring dispatcher servlet:

ContextLoaderListener:

<!-- Creates the Spring Container shared by all Servlets and Filters -->
<context-param>
  <param-name>contextConfigLocation</param-name>
  <param-value>/WEB-INF/applicationContext.xml</param-value>
</context-param>
<listener>
    <!-- loads by default /WEB-INF/applicationContext.xml but this can be overridden above -->
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

Which creates the Spring Container shared by all Servlets and Filters. The ContextLoaderListener will load the main applicationContext configuration file /WEB-INF/applicationContext.xml

DispatcherServlet:

<servlet>
    <description>CDM Remote API</description>
    <servlet-name>cdmlib-remote</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
    <!-- loads by default policy /WEB-INF/cdmlib-remote-servlet.xml  -->
</servlet>

applicationContext.xml

The cdmlib-remote-webapp is configured using the MVC Java Config therefore the applicationContext.xml does not contain <mvc:annotation-driven/> but a <context:annotation-config /> entry:

/WEB-INF/applicationContext.xml

<context:annotation-config />

cdmlib-remote-servlet.xml

This is the configuration of the MVC context of the cdmlib-remote servlet. It contains two parts, of which the first one lets spring find the CdmSpringMVCConfig class which is the main configuration bean for the MVC context. This class defines a couple of component scans to expose further beans to the context:

<!-- 
  Initialize SpringMVCConfig and its dependency SpringSwaggerConfig.
  All further component scans are defined in this mvc configuration class 
-->
<context:component-scan base-package="eu/etaxonomy/cdm/remote/config" />

In addition to the CdmSpringMVCConfig class this component scan also covers the

The second part in this file is a conditional entry is an import directive which is only evaluated when the JVM option -Dspring.profiles.active=remoting is supplied. This import causes the initialization of the HTTP Invoker based remoting services needed by the Taxonomic Editor to be able to connect to the CDM Server:

<!-- FIXME:Remoting Expose remoting services currently only for testing -->
<!-- Using Spring Beans Profile (>3.1) http://spring.io/blog/2011/02/11/spring-framework-3-1-m1-released/ 
  only valid if it is at the end of the xml file activated by the vmarg -Dspring.profiles.active=remoting -->
<beans profile="remoting">
  <import resource="classpath:/eu/etaxonomy/cdm/remoting-services.xml" />
</beans>

CdmSpringMVCConfig

The Java configuration bean for the spring MVC context, that is it is annotated with @Configuration but it has not the @EnableWebMvc annotation, since it directly subclasses @WebMvcConfigurationSupport@. "... An alternative more advanced option is to extend directly from this class and override methods as necessary remembering to add @Configuration to the subclass and @Bean to overridden @Bean methods. For more details see the Javadoc of @EnableWebMvc. ..."

The reason for this is that the method WebMvcConfigurationSupport.requestMappingHandlerMapping() needs to be overridden in the @CdmSpringMVCConfig@. We may be able go without this method override once we no longer need CdmAntPathMatcher. which is only needed since the controllers need absolute method level RequestMapping values in some few cases. TODO

It enables swagger by the type annotation:

@EnableSwagger

and defines a couple of component scans:

@ComponentScan(basePackages = {
        "eu.etaxonomy.cdm.remote.l10n",
        "eu.etaxonomy.cdm.remote.controller",
        "eu.etaxonomy.cdm.remote.service",
        "eu.etaxonomy.cdm.remote.config"
        }
)

CdmSwaggerConfig

This is also a spring java configuration class and thus annotated with @Configuration.
It provides the cdmlib-remote-webapp specific configuration for swagger.

Add picture from clipboard (Maximum size: 40 MB)