Project

General

Profile

Cdmlib-remote-webappConfigurationAndBootstrapping » History » Version 32

Andreas Kohlbecker, 02/10/2017 05:55 PM

1 1 Andreas Kohlbecker
# cdmlib-remote-webapp configuration and bootstrapping
2
3
4 16 Andreas Kohlbecker
{{>toc}}
5
6 2 Andreas Kohlbecker
This page describes how spring mvc in `cdmlib-remote-webapp` is configured and whow the application is being bootstrapped based on this configuration.  
7 1 Andreas Kohlbecker
8 15 Andreas Kohlbecker
## Bootstrap
9 1 Andreas Kohlbecker
10 26 Andreas Kohlbecker
The bootstraping startst with the [[Cdmlib-remote-webappConfigurationAndBootstrapping#webxml|web.xml]] file in which the _main application context_ and the _DispatcherServlet context_ configured to be picked up by the application container.
11 1 Andreas Kohlbecker
12 30 Andreas Kohlbecker
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.
13
14 28 Andreas Kohlbecker
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:
15 15 Andreas Kohlbecker
16 26 Andreas Kohlbecker
* Main application context (beans such as data sources, jpa configuration, business services) --> [[Cdmlib-remote-webappConfigurationAndBootstrapping#applicationContextxml|/WEB-INF/applicationContext.xml]]
17 27 Andreas Kohlbecker
  * -[has child context]-> dispatcher servlet context (MVC specific configuration, components, beans) --> [[Cdmlib-remote-webappConfigurationAndBootstrapping#cdmlib-remote-servletxml|/WEB-INF/cdmlib-remote-servlet.xml]]
18 15 Andreas Kohlbecker
19
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.
20
21
For very detailed explanation on this topic, see http://stackoverflow.com/questions/15818047/spring-namespace-vs-contextconfiglocation-init-parameters-in-web-xml#answer-15825207
22
23
### DispatcherServlet context
24
25 1 Andreas Kohlbecker
The DispatcherServlet builds the MVC context, handles all HTTP requests and delegates them to other components of the MVC architecture.
26 15 Andreas Kohlbecker
27 26 Andreas Kohlbecker
The configuration file for this context is the [[Cdmlib-remote-webappConfigurationAndBootstrapping#cdmlib-remote-servletxml|/WEB-INF/cdmlib-remote-servlet.xml]]
28 15 Andreas Kohlbecker
29 22 Andreas Kohlbecker
### main application context
30 15 Andreas Kohlbecker
31
The _main application context_ the the context in which the core cdm application with model, persistence and services is initialized.  
32 19 Andreas Kohlbecker
33 26 Andreas Kohlbecker
The configuration file for this context is the [[Cdmlib-remote-webappConfigurationAndBootstrapping#applicationContextxml|/WEB-INF/applicationContext.xml]]
34 15 Andreas Kohlbecker
35 31 Andreas Kohlbecker
## Java Spring configuration classes & packages
36
37
The CDM-Library has a couple of packages in which Java Spring configuration classes are located:
38
39
###  eu.etaxonomy.cdm.api.config
40
41
The package eu.etaxonomy.cdm.api.config contains spring configurations 
42
which are loaded automatically into the root application context.
43
These classes are injected into the context via component scan.
44
45
Found in:
46
47
* cdmlib/cdmlib-services
48
49
### eu.etaxonomy.cdm.opt.config
50
51
The package eu.etaxonomy.cdm.opt.config contains spring configurations 
52
which can be loaded into the **root WebApplicationContext** loaded via 
53
*Spring's ContextLoaderListener*, but which are optional.
54
55
This package must not be covered by a component scan the bean in here should be **added 
56
individually to the context**. 
57
58
59
Found in:
60
61 32 Andreas Kohlbecker
* cdmlib/cdmlib-remote
62 31 Andreas Kohlbecker
63
### eu.etaxonomy.cdm.remote.config
64
65
The package eu.etaxonomy.cdm.remote.config contains spring configurations 
66
which are to be loaded into the **child WebApplicationContext** loaded via 
67
Spring's DispatcherServlet. These classes are injected into the context via **component scan**.
68
69
Found in:
70 1 Andreas Kohlbecker
71 32 Andreas Kohlbecker
* cdmlib/cdmlib-remote-webapp
72 31 Andreas Kohlbecker
* cdmlib-remote
73
74
### eu.etaxonomy.cdm.addon.config
75
76
The package eu.etaxonomy.cdm.addon.config is an **extension point** where
77
addon-modules can place their Spring configuration classes. 
78
A component scan defined in cdmlib-remote-webapp will find them:
79
  
80
~~~xml
81
  <context:component-scan base-package="eu/etaxonomy/cdm/addon/config" />
82
~~~
83
84
Found in:
85
86 32 Andreas Kohlbecker
* cdmlib/cdmlib-remote-webapp
87 31 Andreas Kohlbecker
* cdm-vaadin
88
89
90 15 Andreas Kohlbecker
## Participating classes and configuration files
91
92
### web.xml
93 7 Andreas Kohlbecker
94
The file `/cdmlib-remote-webapp/src/main/webapp/WEB-INF/web.xml` contains an listener entry and the configuration of the Spring dispatcher servlet:
95
96 1 Andreas Kohlbecker
 **ContextLoaderListener:** 
97
98
~~~
99
<!-- Creates the Spring Container shared by all Servlets and Filters -->
100 15 Andreas Kohlbecker
<context-param>
101
  <param-name>contextConfigLocation</param-name>
102
  <param-value>/WEB-INF/applicationContext.xml</param-value>
103
</context-param>
104
<listener>
105 7 Andreas Kohlbecker
    <!-- loads by default /WEB-INF/applicationContext.xml but this can be overridden above -->
106 15 Andreas Kohlbecker
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
107 7 Andreas Kohlbecker
</listener>
108 9 Andreas Kohlbecker
~~~
109 25 Andreas Kohlbecker
110 28 Andreas Kohlbecker
Which creates the Spring Container shared by all Servlets and Filters. The ContextLoaderListener will load the main [[Cdmlib-remote-webappConfigurationAndBootstrapping#applicationContextxml|applicationContext configuration file]] `/WEB-INF/applicationContext.xml` 
111 7 Andreas Kohlbecker
112
 **DispatcherServlet:** 
113
114
~~~
115 1 Andreas Kohlbecker
<servlet>
116
    <description>CDM Remote API</description>
117
    <servlet-name>cdmlib-remote</servlet-name>
118 7 Andreas Kohlbecker
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
119
    <load-on-startup>1</load-on-startup>
120 1 Andreas Kohlbecker
    <!-- loads by default policy /WEB-INF/cdmlib-remote-servlet.xml  -->
121
</servlet>
122
~~~
123
124
### applicationContext.xml
125 17 Andreas Kohlbecker
126 28 Andreas Kohlbecker
The `cdmlib-remote-webapp` is configured using the [MVC Java Config](http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#mvc-config-enable) therefore the `applicationContext.xml` does not contain `<mvc:annotation-driven/>` but a `<context:annotation-config />` entry:
127 17 Andreas Kohlbecker
128 28 Andreas Kohlbecker
* **`<context:annotation-config />`** activates the annotations only on beans which have already been discovered and registered, see http://howtodoinjava.com/2014/07/19/spring-mvc-difference-between-contextannotation-config-vs-contextcomponent-scan/ for detailed explanations.
129 1 Andreas Kohlbecker
130 11 Andreas Kohlbecker
 `/WEB-INF/applicationContext.xml` 
131
132 8 Andreas Kohlbecker
~~~
133
<context:annotation-config />
134
~~~
135 15 Andreas Kohlbecker
136
### cdmlib-remote-servlet.xml
137 20 Andreas Kohlbecker
138 28 Andreas Kohlbecker
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 [[Cdmlib-remote-webappConfigurationAndBootstrapping#CdmSpringMVCConfig|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:
139 20 Andreas Kohlbecker
140
~~~
141
<!-- 
142
  Initialize SpringMVCConfig and its dependency SpringSwaggerConfig.
143
  All further component scans are defined in this mvc configuration class 
144
-->
145
<context:component-scan base-package="eu/etaxonomy/cdm/remote/config" />
146
~~~
147 21 Andreas Kohlbecker
In addition to the CdmSpringMVCConfig class this component scan also covers the 
148 20 Andreas Kohlbecker
149 21 Andreas Kohlbecker
150 20 Andreas Kohlbecker
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:
151
152
~~~
153 1 Andreas Kohlbecker
<!-- FIXME:Remoting Expose remoting services currently only for testing -->
154
<!-- Using Spring Beans Profile (>3.1) http://spring.io/blog/2011/02/11/spring-framework-3-1-m1-released/ 
155
  only valid if it is at the end of the xml file activated by the vmarg -Dspring.profiles.active=remoting -->
156
<beans profile="remoting">
157
  <import resource="classpath:/eu/etaxonomy/cdm/remoting-services.xml" />
158 20 Andreas Kohlbecker
</beans>
159
~~~
160
161
### CdmSpringMVCConfig
162
163 23 Andreas Kohlbecker
164
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. ..."_
165
166
167
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** 
168 21 Andreas Kohlbecker
169
It enables swagger by the type annotation:
170
171
~~~
172
@EnableSwagger
173
~~~
174
and defines a couple of component scans:
175
176
~~~
177
@ComponentScan(basePackages = {
178
        "eu.etaxonomy.cdm.remote.l10n",
179
        "eu.etaxonomy.cdm.remote.controller",
180
        "eu.etaxonomy.cdm.remote.service",
181
        "eu.etaxonomy.cdm.remote.config"
182
        }
183
)
184
~~~
185
186
187
### CdmSwaggerConfig
188
 
189
190 29 Andreas Kohlbecker
This is also a spring java configuration class and thus annotated with `@Configuration`.
191 21 Andreas Kohlbecker
It provides the cdmlib-remote-webapp specific configuration for swagger.