In my project, we have a spring mvc application.
It has got both applicationcontext.xml as well as -servlet.xml config files.
Bean definitons are spread in both the files.
I want to know when we have -servlet.xml wats the need for applicationcontext.xml?
Please provide any explanation in this area.
applicationContext.xml will have the bean definitions of the core spring components.
project-servlet.xml will have bean definitions of indivisual servlets.
-servlet.xml can have references to applicationContext.xml not the other way round.
What you refer as applicationContext.xml is the root application context (you put beans there when you need application-wide access to them) and what you refer as the [servlet]-context.xml is a specific Spring Bean configuration xml for Spring MVC's DispatcherServlet.
servlet-context is specific to a servlet and application context is shared for whole application. So when you define a Bean in servlet-context.xml the Bean is available to the context of that specific servlet, but when you define a Bean in application-context.xml it is available in the whole application. So if you have multiple dispatcherServlet you can have separate servlet-context for each servlet. But there is only one application-context for the application
Related
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 created a servlet filter which is using some Autowired fields. For making it work I declared it as DelegatingFilterProxy in web.xml . Before this filter, my enitre spring config was in dispatcher-servlet.xml but for some reason declaring bean for this filter was not working in dispacher-servlet. So, I declared it in applicationContext.xml. It started working then but Autwired fields inside filter were then throwing null. To tackle with it I moved
<context:component-scan base-package="com.myproj.abc" />
to applicationContext, filter started working then but url paths defined by my controller classes are no longer mapped. So I need to pull following two lines also in applicationContext
<mvc:default-servlet-handler />
<mvc:annotation-driven />
This solves the issue. But I was wondering is this the right place for all this code? Because Spring security and for static resources and view mapping all these code goes in dispatcher. In one of my other project I faced same issue and there I did like this, declared only following line in applicationContext
<context:component-scan base-package="com.myproj.abc" />
And in dispatcher-servlet I change component scan package to controller only and kept all other code there only(in dispatcher)
<context:component-scan base-package="com.myproj.abc.controller" />
Could anyone please enlighten me on this confusion.
Some terminology: ServletContext is the class. Servlet context is the Spring ApplicationContext for the DispatcherServlet. Application context, also know as root context is the ApplicationContext loaded by the ContextLoaderListener and stored in the web application's ServletContext. It is therefore available to other web application components.
The servlet context is loaded by the DispatcherServlet. The DispatcherServlet retrieves the application context from the ServletContext and uses it as the parent of the servlet context.
A servlet Filter is web application component that has no relation to the DispatcherServlet, ie. it doesn't know about the servlet context.
The javadoc for DelegatingFilterProxy states
Supports a "targetBeanName" filter init-param in web.xml, specifying
the name of the target bean in the Spring application context.
So the Filter bean has to be declared in the application context, not the servlet context.
Put all beans that have application scope in the application context.
Put all beans that have relevance to the MVC stack in the servlet context.
Your component-scan should scan the appropriate packages to support the two rules/suggestions above.
Further reading:
What is the difference between ApplicationContext and WebApplicationContext in Spring MVC?
Web-application context/ root application context and transaction manager setup
Difference between applicationContext.xml and spring-servlet.xml in Spring Framework
What type of information should be present in the dispatcher-servlet.xml and applicationContext.xml?
The applicationContext.xml is loaded by the ContextLoadeListener and should contain your shared/global beans. Things like the datasource, jms connecetionfactories, services, repositories etc.
Your dispatcher-servlet.xml is loaded by the DispatcherServlet and should contain only web related things like controllers, viewresolvers, exceptionhandlers etc.
This is a general rule of thumb of course.
I am using Resteasy and Spring for my project. As Resteasy document said: http://docs.jboss.org/resteasy/docs/3.0.1.Final/userguide/html_single/index.html#RESTEasy_Spring_Integration.
I need to add a listener in the web.xml file:
<listener>
<listener-class>org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap</listener-class>
<listener>
<listener-class>org.jboss.resteasy.plugins.spring.SpringContextLoaderListener</listener-class>
However, in my project we also used a cms called magnolia, and magnolia also has an implementation for SpringContextLoaderListener. If I put both context listener. The magnolia won't be started when I run the app.
So according to the Resteasy document said:
If you do not use a Spring ContextLoaderListener to create your bean factories, then you can manually register the RESTeasy BeanFactoryPostProcessor by allocating an instance of org.jboss.resteasy.plugins.spring.SpringBeanProcessor. You can obtain instances of a ResteasyProviderFactory and Registry from the ServletContext attributes org.jboss.resteasy.spi.ResteasyProviderFactory and org.jboss.resteasy.spi.Registry. (Really the string FQN of these classes). There is also a org.jboss.resteasy.plugins.spring.SpringBeanProcessorServletAware, that will automatically inject references to the Registry and ResteasyProviderFactory from the Servlet Context. (that is, if you have used RestasyBootstrap to bootstrap Resteasy).
Does anyone knows how can I achieve that without using Resteasy ContextLoaderListener? What do I need to put in my spring applicationContext xml file?
I've also had problem with RestEasy SpringContextListener (properties placeholders ${...} weren't processed - RESTEASY-787, Spring java config didn't work etc.).
So it's enough to drop RestEasy SpringContextListener and use default org.springframework.web.context.ContextLoaderListener or whatever listener you need to. You just have to define Spring bean in your Spring XML configuration like this:
<bean class="org.jboss.resteasy.plugins.spring.SpringBeanProcessorServletAware"/>
Than RestEasy should work even without their special SpringContextListener. It works for me.
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.