I created a simple spring-web-mvc project based on maven. The sample includes two configuration files. One in src / main / resources / spring / application-config.xml
and a second in src / main / webapp / WEB-INF / mvc-config.xml
Is that config normal? I think it is just configuration splitting basics mvc stuff in mvc-config.xml and application-config.xml for spring commons or?
For a web application then that is fairly normal - although the naming convention for the two files is often dispatcher-servlet.xml and applicationContext.xml.
The dispatcher-servlet.xml (or mvc-config.xml as in your question) is the configuration file for the web application context and contains the web specific beans and configuration for Spring MVC. It is loaded by the DispatcherServlet when the application starts up.
The applicationContext.xml (or application-config.xml as in your question) is the configuration file for the main Spring application context and contains the non-web business beans (typically services, DAOs etc). This file is often spilt into fragments - with a fragment containing the beans for each logical layer within the app. This file is typically loaded by the ContextLoaderListener defined in the web.xml.
Spring automatically sets the main application context as the parent of the web application context. This ensures that web components (such as controllers) have access to business beans in the application context. However, business beans are not able to see beans in the web application context.
Related
What is the difference between DispatcherServlet and ContextLoaderListener in Spring framework? Do we need to configure both of them in web.xml when we are using spring framework?
AFAIK each DispatcherServlet will have a WebApplicationContext. By default the DispatcherServlet looks for a spring configuration file named [appname]-servlet.xml under WEB-INF folder.
Do we need to configure DispatcherServlet?
Yes, every spring application should configure DispatcherServlet as it is the one through which all the requests are routed. It decides the appropriate method of the controller class to handle the request. Once controller returns the model along with the logical view, DispatcherServlet takes the help of ViewResolver to resolve the view (generally JSPs) and will pass the model data to the view, which is finally rendered on the browser.
Do we need to configure ContextLoaderListener?
No, this is not mandatory. Spring applications can live with out ContextLoaderListener.
Why do we need ContextLoaderListener?
Usually when we build multi-tier applications we don't want to clutter all the beans in one config file [appname]-servlet.xml. For example if you configure spring security you wanted to include all those beans in security-context.xml, in the same way all the beans belonging to service layer are configured in applicationContext.xml and some would like to configure beans belonging to DAO layer in dao-context.xml. So when you configure all these beans in different context files, you need to let know spring that these files exist as spring only knows about [appname]-servlet.xml. ContextLoaderListener will help spring recognize all the other context files.
Hope this helps!
The root WebApplicationContext is a Spring Application Context shared across the application.
A DispatcherServlet instance actually has its own
WebApplicationContext.
One can have multiple DispatcherServlet instances in an application, and each will have its own WebApplicationContext.
The root WebApplicationContext is shared across
the application, so if you have a root WebApplicationContext and
multiple DispatcherServlets, the DispatcherServlets will share the
root WebApplicationContext.
However, for a simple Spring MVC application, one can even have a situation where there is no need to have a root WebApplicationContext. A DispatcherServlet would still have its own WebApplicationContext, but it doesn’t actually need to have a parent root WebApplicationContext.
So, which beans should go in the root Web Application Context and which beans should go in the DispatcherServlet’s Web Application Context?
Well, general beans such as services and DAOs make their way in root Web Application Context, and more web-specific beans such as controllers are included in DispatcherServlet’s Web Application Context.
When DispatcherServlet starts up, it creates a Spring application context and starts
loading it with beans declared in the configuration files or classes that it’s given.
But in Spring web applications, there’s often another application context. This
other application context is created by ContextLoaderListener
Whereas DispatcherServlet is expected to load beans containing web components
such as controllers, view resolvers, and handler mappings, ContextLoaderListener is
expected to load the other beans in your application. These beans are typically the
middle-tier and data-tier components that drive the back end of the application.
Good luck!
I start to learn spring recently.
My goal is to use spring MVC to do restful api
I know spring MVC is web framework in spring
I know that in spring,there is beans.xml
And in spring MVC , there is servletname-servlet.xml
I want to know where is difference??
Is it means if I use spring MVC,I don't need to use beans.xml??
Please give me some way or give me example project link with spring and spring MVC together
The servletname-servlet.xml defines the beans for one servlet's app context. There can be number of servlets in a webapp and for every servlet we have servletname-servlet.xml (e.g. spring1-servlet.xml for servlet1, spring2-servlet.xml for servlet2).
Beans defined in servletname-servlet.xml can reference beans in beans.xml, but not vice versa.
All Spring MVC controllers must go in the servletname-servlet.xml context.
Beans.xml contain beans that are shared between all servlets in a webapp.Usually the beans.xml context is not necessary if you have only one servlet in your webapp.
You could define all your beans in servletname-servlet.xml but it's not a good practice.
Usually if you create a web application in 'pure' spring (ie. without spring MVC) then you will add ContextLoaderListener as a filter to your web.xml. Then spring will look for applicationContext.xml when you will usually import beans.xml.
In servletname-servlet.xml you define servlets. Servlets can refer other beans. So it's good practice to separate front (servlets) from backend (beans.xml).
Also remember that beans declared in servletname-servlet.xml are overriding the definitions of any beans defined with the same name in the global scope.
See also better answer at: ContextLoaderListener or not?
I have an existing web application developed with JSF 2.0 for the view layer and Spring 3 for data access, service and security layers. Then I tried to create the mobile application so I used a Spring #controller class to listen on ws requests but the problem is that when I insert data by mobile application and web application a duplicated entry exception was thrown. It seems to me that Spring create two instances of my Dao in different application contexts one for my managed beans and other one for controller.
NB: I use criteria for data base querys
Can some one help me ?
Finally, i can use a spring controller with jsf web application. i created a applicationContext.xml file then i moved all my beans into it and i conserve my servlet.xml file but with no beans inside, that's will create one root webapp context, by consequence hibernate will create one session for the managed beans and the controller
Difference between applicationContext.xml and spring-servlet.xml in Spring
Where to put application level beans in Spring MVC? Into root-context.xml or into servlet-context.xml?
Beans declared in root-context.xml (services) are visible for beans in servlet-context.xml (controllers), but not the other way around. Therefore there can be a dependency from controllers to services, but the reverse dependency is forbidden by Spring.
That being said put MVC-independent code (services, DAOs, etc.) in main context and put web-only stuff in servlet context.
I've looked at a bunch of sample projects and I can't seem to tease out a common best practice. I've seen Spring bean config files sometimes go in the src/main/webapp/WEB-INF directory. I've seen this in conjunction with with a Servlet definition in web.xml like this:
<servlet>
<servlet-name>my-stuff</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/my-stuff-servlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
But I've also seen bean config files included within web.xml top level -- i.e. outside of a Servlet. What does this mean? Is this for cross-Servlet beans? Sometimes it's in the src/main/webapp/WEB-INF directory and sometimes it's in src/main/resources. Also I've seen other bean config files defined in WAR modules with just about everything in src/main/resources.
I've read and re-read the Spring documentation, but the only convention I found is that by default a Servlet context config file should be in the src/main/webapp/WEB-INF directory named {servlet-name}-servlet.xml.
So what's the best practice and why?
Application contexts in Spring can form hierarchies where child context has access to beans defined in parent context.
A typical Spring MVC web application contains a hierarchy with two levels:
Root web application context loaded by ContextLoaderListener.
Config location of this context is applicationContext.xml by default and can be configured using <context-param> named contextConfigLocation, i.e. at the top level of web.xml. This context usually contains a core application logic.
Servlet-specifc context loaded by DispatcherServlet. Its config location is by default <servletname>-servlet.xml and can be configured using <init-param> named contextConfigLocation, i.e. at servlet level. This context usually contains a Spring MVC-related stuff (controllers, etc) since DispatcherServlet is a part of Spring MVC.
The latter context is a child of the former.
If web application doesn't use Spring MVC as a presentation framework, it doesn't have DispatcherServlet and its context. Some extremely simple Spring MVC samples doesn't have ContextLoaderListener and the root context (however, you need root context for cross-servlet functionality such as Spring Security).
Config files of web application are by default located in webapp's root folder. However, they can be placed in the classpath (i.e. in src/main/webapp), in this case they are accessed via classpath: prefix. This may be useful if you are going to use some of these files in integration tests without servlet container. Also classpath: prefix may be useful when you want to load a config file from a separate artifact, i.e. from a jar file in /WEB-INF/lib.
I think it is often good style to keep the code, its spring configuration an in a separate JAR that is included into the WAR, such that the WAR is basically empty but for web.xml and the like. This saves you from even asking this question. :-) You can reference those spring configurations with classpath: prefix.
One advantage of this layout is that you can easily write Unittests that instantiate the complete Spring configuration of the WAR within the JAR. I would not necessarily recommend to use this for actual tests (although you can do integration tests this way), but you get a quick feedback when you accidentially break the overall structure of the config files without having to redeploy the application.
If you really need to put spring configuration files into the WAR (perhaps since it also references beans that are implemented in the WAR itself) I would also put them into the normal resources path /WEB-INF/classes, for the reasons discussed above.