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. |