Project

General

Profile

Cdmlib-remote-webappConfigurationAndBootstrapping » History » Version 41

Andreas Müller, 11/08/2021 09:44 PM

1 1 Andreas Kohlbecker
# cdmlib-remote-webapp configuration and bootstrapping
2
3
4 16 Andreas Kohlbecker
{{>toc}}
5
6 34 Andreas Müller
This page describes how spring mvc in `cdmlib-remote-webapp` is configured and how the application is being bootstrapped based on this configuration.  
7 1 Andreas Kohlbecker
8 15 Andreas Kohlbecker
## Bootstrap
9 1 Andreas Kohlbecker
10 35 Andreas Müller
The bootstraping startst with the [[Cdmlib-remote-webappConfigurationAndBootstrapping#webxml|web.xml]] file in which the _main application context_ and the _DispatcherServlet context_ are configured to be picked up by the application container.
11 1 Andreas Kohlbecker
12 37 Andreas Müller
In a Spring MVC web application you will typically have a **root WebApplicationContext** 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 30 Andreas Kohlbecker
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 36 Andreas Müller
The _main application context_ is 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 38 Andreas Müller
The package *eu.etaxonomy.cdm.api.config* contains spring configurations 
42 31 Andreas Kohlbecker
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 39 Andreas Müller
The package *eu.etaxonomy.cdm.opt.config* contains spring configurations 
52 31 Andreas Kohlbecker
which can be loaded into the **root WebApplicationContext** loaded via 
53
*Spring's ContextLoaderListener*, but which are optional.
54
55 40 Andreas Müller
This package must not be covered by a component scan. The bean(s) in here should be **added 
56 31 Andreas Kohlbecker
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 33 Andreas Kohlbecker
addon-modules can place their Spring configuration classes so that the addon 
78
can be bootstrapped. A component scan defined in cdmlib-remote-webapp will 
79
find them.
80 31 Andreas Kohlbecker
81 33 Andreas Kohlbecker
82 31 Andreas Kohlbecker
Found in:
83 32 Andreas Kohlbecker
84 31 Andreas Kohlbecker
* cdmlib/cdmlib-remote-webapp
85
* cdm-vaadin
86
87 15 Andreas Kohlbecker
## Participating classes and configuration files
88
89
### web.xml
90 7 Andreas Kohlbecker
91 41 Andreas Müller
The file `/cdmlib-remote-webapp/src/main/webapp/WEB-INF/web.xml` contains a listener entry and the configuration of the Spring dispatcher servlet:
92 7 Andreas Kohlbecker
93 1 Andreas Kohlbecker
 **ContextLoaderListener:** 
94
95
~~~
96
<!-- Creates the Spring Container shared by all Servlets and Filters -->
97 15 Andreas Kohlbecker
<context-param>
98
  <param-name>contextConfigLocation</param-name>
99
  <param-value>/WEB-INF/applicationContext.xml</param-value>
100
</context-param>
101
<listener>
102 7 Andreas Kohlbecker
    <!-- loads by default /WEB-INF/applicationContext.xml but this can be overridden above -->
103 15 Andreas Kohlbecker
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
104 7 Andreas Kohlbecker
</listener>
105 9 Andreas Kohlbecker
~~~
106 25 Andreas Kohlbecker
107 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` 
108 7 Andreas Kohlbecker
109
 **DispatcherServlet:** 
110
111
~~~
112 1 Andreas Kohlbecker
<servlet>
113
    <description>CDM Remote API</description>
114
    <servlet-name>cdmlib-remote</servlet-name>
115 7 Andreas Kohlbecker
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
116
    <load-on-startup>1</load-on-startup>
117 1 Andreas Kohlbecker
    <!-- loads by default policy /WEB-INF/cdmlib-remote-servlet.xml  -->
118
</servlet>
119
~~~
120
121
### applicationContext.xml
122 17 Andreas Kohlbecker
123 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:
124 17 Andreas Kohlbecker
125 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.
126 1 Andreas Kohlbecker
127 11 Andreas Kohlbecker
 `/WEB-INF/applicationContext.xml` 
128
129 8 Andreas Kohlbecker
~~~
130
<context:annotation-config />
131
~~~
132 15 Andreas Kohlbecker
133
### cdmlib-remote-servlet.xml
134 20 Andreas Kohlbecker
135 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:
136 20 Andreas Kohlbecker
137
~~~
138
<!-- 
139
  Initialize SpringMVCConfig and its dependency SpringSwaggerConfig.
140
  All further component scans are defined in this mvc configuration class 
141
-->
142
<context:component-scan base-package="eu/etaxonomy/cdm/remote/config" />
143
~~~
144 21 Andreas Kohlbecker
In addition to the CdmSpringMVCConfig class this component scan also covers the 
145 20 Andreas Kohlbecker
146 21 Andreas Kohlbecker
147 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:
148
149
~~~
150 1 Andreas Kohlbecker
<!-- FIXME:Remoting Expose remoting services currently only for testing -->
151
<!-- Using Spring Beans Profile (>3.1) http://spring.io/blog/2011/02/11/spring-framework-3-1-m1-released/ 
152
  only valid if it is at the end of the xml file activated by the vmarg -Dspring.profiles.active=remoting -->
153
<beans profile="remoting">
154
  <import resource="classpath:/eu/etaxonomy/cdm/remoting-services.xml" />
155 20 Andreas Kohlbecker
</beans>
156
~~~
157
158
### CdmSpringMVCConfig
159
160 23 Andreas Kohlbecker
161
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. ..."_
162
163
164
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** 
165 21 Andreas Kohlbecker
166
It enables swagger by the type annotation:
167
168
~~~
169
@EnableSwagger
170
~~~
171
and defines a couple of component scans:
172
173
~~~
174
@ComponentScan(basePackages = {
175
        "eu.etaxonomy.cdm.remote.l10n",
176
        "eu.etaxonomy.cdm.remote.controller",
177
        "eu.etaxonomy.cdm.remote.service",
178
        "eu.etaxonomy.cdm.remote.config"
179
        }
180
)
181 1 Andreas Kohlbecker
~~~
182 21 Andreas Kohlbecker
183
184
### CdmSwaggerConfig
185
 
186
187 29 Andreas Kohlbecker
This is also a spring java configuration class and thus annotated with `@Configuration`.
188 33 Andreas Kohlbecker
It provides the cdmlib-remote-webapp specific configuration for swagger.