Spring project with multimodule - spring

I am looking to create a Spring web application and I use Maven as the build automation tool.
I prefer to go with multimodule application. The reason for modules are:
I have an admin module in my application and user module. The code
changes in user module should not require testing of admin module.
Different development team work in user and admin modules
On POM module side I tend to go as follows
project/pom.xml #pom with <modules> element
project/parent/pom.xml #Parent pom
project/moduleX/pom.xml #module 'X'
project/moduleY/pom.xml #module 'Y'
Question is, when I go with modules approach are there any best practice I need to follow on Spring side?

Use per-module applicationContex
You might want application context for each module:
...
<servlet>
<servlet-name>main-project</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>WEB-INF/config/main-project-servlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>main-project</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/config/applicationContext-moduleX.xml
/WEB-INF/config/applicationContext-moduleY.xml
</param-value>
</context-param>
...
You need then a way to put in the same directory, /WEB-INF/config/ for example, the various application context by Maven Assembly Plugin or by overlaying with Maven War Plugin.

Related

Servlet Web Application Context from filter

I try to get the spring web application context from a filter.
I was previously getting it through:
WebApplicationContextUtils.getRequiredWebApplicationContext(request.getServletContext())
It was ok, because I was getting what is called I think the ROOT web application context.
Now, I wanted to move all my spring definition like that in web.xml :
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- Configure DispatcherServlet to use AnnotationConfigWebApplicationContext instead of default XmlWebApplicationContext. -->
<init-param>
<param-name>contextClass</param-name>
<param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>
</init-param>
<!-- Custom web configuration annotated class. -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>foo.bar.WebConfiguration</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
I removed the "old" definition from web.xml :
<!-- <context-param> -->
<!-- <param-name>contextConfigLocation</param-name> -->
<!-- <param-value>/WEB-INF/dispatcher-servlet.xml</param-value> -->
<!-- </context-param> -->
<!-- <listener> -->
<!-- <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> -->
<!-- </listener> -->
Now, I have no more "ROOT" web application context, and the filter cannot get the another web application context.
I saw that there is another call :
WebApplicationContextUtils.getWebApplicationContext(sc, attrName)
it allows to specify as second argument the "attribute", it is in fact the web application context you want.By default, it is "org.springframework.web.context.WebApplicationContext.ROOT".
I think I have to call this method but I don't know what to put as second parameter.
PS : I also tried to use org.springframework.web.filter.DelegatingFilterProxy, but tomcat throwed the error that he dont find the classic (ROOT) web application context :
java.lang.IllegalStateException: No WebApplicationContext found: no ContextLoaderListener registered?
BUT THERE IS ANOTHER CONTEXT, it is just defined in another way. It is not possible I am the only one trying to get another context that the ROOT.
Thanks to have read so far.
I just read your answer, and yes I figured it out yesterday night ;-)
I added the ROOT context, defining it like that:
<context-param>
<param-name>contextClass</param-name>
<param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>
</context-param>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>foo.bar.WebConfiguration</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
And its working, the filter can acces to the service directly with Autowiring.
I still have the feeling that my architecture is dirty because the ROOT and "dispatcher" context are the same, I think it's not a good practice.
Maybe I'll try later to split the "WebConfiguration" in two.
Thank you anyway!

Location of groovy based bean definition configuration in a Spring MVC application

I have seen that Spring 4 has a feature to define / having a groovy file for bean definitions instead of an XML file. I already have a Spring MVC application with mvc-dispatcher-servlet.xml for my bean definitions. But I want to go with Groovy based bean definition for my Spring MVC application. But, I am not sure where to place the groovy file and where do I need to refer it/ configure it to Load the bean definitions properly. Can somebody help or provide refrence?
use the GroovyWebApplicationContext ,
Web.xml
<servlet>
<servlet-name>mvc-dispatcher</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<init-param>
<param-name>contextClass</param-name>
<param-value>
org.springframework.web.context.support.GroovyWebApplicationContext
</param-value>
</init-param>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:/spring/dispatcherServlet.groovy</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
this is not a full example, but it is a good start

application-config.xml vs mvc-config.xml in spring

Im a newbie to Spring and trying to understand the web.xml file.
I have created a new SPring MVC Maven project using STS,
I'm little bit confused between the application-config.xml vs mvc-config.xml file...
mvc-config.xml contains the servlet mappings but what information does the application-config file contains..
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/application-config.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!--
- Servlet that dispatches request to registered handlers (Controller implementations).
-->
<servlet>
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/mvc-config.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
Usually the mvc configuration(/WEB-INF/mvc-config.xml) contains the the beans that are needed by the controller layer (e.g. the controllers, view resolvers ...) The application configuration(classpath:spring/application-config.xml) is for the model layer (here you can define daos, services...)

Double (Scheduler) bean initialization

I have 2 contexts in my application, one is "spring" (Web+MVC), second is "rpc" (just RPC service). Both of them inherits configs from the "spring" directory (there are 4 files: app-config.xml, infrastructure-config.xml, integration-config.xml and security-config.xml).
The app-config.xml contains initialization of the Quartz Scheduler.
So, if I starts my application, there are two Quartz Scheduler threads and all scheduled services are invoked twice. Is that because I inheriting settings from app-confix.xml into both contexts ?
I thought that beans deffined in parent config are initialized only once and shared between context which inheriting that parent config.
Thanks for any advice :).
Example from my web.xml.
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/spring/*-config.xml
</param-value>
</context-param>
<servlet>
<servlet-name>rpc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>0</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>rpc</servlet-name>
<url-pattern>/rpc/*</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>spring</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>spring</servlet-name>
<url-pattern>/web/*</url-pattern>
</servlet-mapping>
In your configuration two independent contexts are getting created. Just the fact that they use the same files doesn't cause spring to create a common parent context.
What you need to do is setup a contextLoaderListener in the web.xml - give it the common config file and then exclude it from the servlets config. The Listener will create the root context and bind it to the servlet context - both the servlets will then link to that as the parent context.

Multiple config files for Spring Security

I'm quite new to all things Spring, and right now I'm developing an application that uses Spring, Spring MVC and Spring Security.
My problem is that I'm using two dispatcher Servlets, one for /csm/*.html and another one for *.html and I'd like to have one Spring Security configuration file per servlet.
Is this possible at all?, if so, could you point me to an example?.
This answer relates to springframework 2.5.6, it might have changed in later versions.
use the pattern /WEB-INF/[servlet-name]-servlet.xml or specify it in the web.xml like this:
<servlet>
<servlet-name>handler</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<!-- override default name {servlet-name}-servlet.xml -->
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring-myconfig.xml</param-value>
</init-param>
<load-on-startup>2</load-on-startup>
</servlet>
If you do not set the contextConfigLocation it defaults to handler-servlet.xml (at least in this example).
application wide stuff belongs into /WEB-INF/applicationContext.xml.
But you also can change the default and even add multiple files:
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
WEB-INF/spring-dao-hibernate.xml,
WEB-INF/spring-services.xml,
WEB-INF/spring-security.xml
</param-value>
</context-param>
you can find a more specific answer on the spring website, the documentation is quite good.

Resources