Double (Scheduler) bean initialization - spring

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.

Related

Understanding spring dispatcher servlet initialization

Here is how spring documentation recomends to initialize dispatcherServlet:
<web-app>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/root-context.xml</param-value>
</context-param>
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value></param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
</web-app>
My question is about providing an empty param-value inside the init-param tag. Despite defining that param as context-param we still provide the empty value. Therefore contextConfigLocation should be null when passes to servlet's init() method. What's wrong, correct me please.
In Spring Web Applications, there are two types of container, each of which is configured and initialized differently.
Application Context
Web Application Context
Application context is inialised by config file's that you specified in as context-params and picked up by ContextLoaderListener. This is purely i would consider as business logic related beans.
Web application context is child of application context which may or may not be present. Each DispatcherServlet will have associated WebApplicationContext and which takes spring beans from your init-params to create context.
Whatever beans are available in the ApplicationContext can be referred to from each WebApplicationContext.
Reason why we have two different bean configurations is to keep a clear separation between middle-tier services such as business logic components and data access classes (that are typically defined in the ApplicationContext) and web- related components such as controllers and view resolvers (that are defined in the WebApplicationContext per Dispatcher Servlet).

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

How do you share Spring beans between different Spring contexts?

We have an application which uses Spring BlazeDS integration. So far we have just been using Spring and Flex, and it is working fine. We now have a requirement to add some Spring MVC controllers as well. The Spring BlazeDS documentation states that the way to do this is to declare two sperate contexts in the web.xml, as follows:
<servlet>
<servlet-name>flex</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>flex</servlet-name>
<url-pattern>/messagebroker/*</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>spring-mvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>spring-mvc</servlet-name>
<url-pattern>/spring/*</url-pattern>
</servlet-mapping>
Here is my question: There are Spring beans which are required to be used within both contexts - the spring-mvc one and the flex one. How can one do this - how can one declare a bean (either in xml or by component scanning) in one context and allow it to be shared with beans declared in the other context?
Thanks !
Create a parent context by using ContextLoaderListener. The DispatcherServlet contexts will automatically become children of that context.
Create your shared beans in the parent context and refer to them in beans in the child contexts.
If you are using <component-scan> make sure you don't accidentally scan classes into multiple contexts. See my answer here.
Add this to your web.xml:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/YOUR_APP_CONTEXT.xml</param-value>
</context-param>
Both beans defined via scanning and direct definitions will be available for your BlazeDS and SpringMVC endpoints.

How to add a Filter in Spring (with BlazeDS)

I want to add a filter to map a specific path in URL.
My server side used Spring 2.5.x, BlazeDS (servlet) with TomCat server.
So, my web.xml file is composed like that :
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/spring-main-config.xml
</param-value>
</context-param>
<filter>
<filter-name>FacebookOAuthFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>FacebookOAuthFilter</filter-name>
<url-pattern>/fbauth</url-pattern>
</filter-mapping>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- Spring MVC Servlet (that will route HTTP requests to BlazeDS) -->
<servlet>
<servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring-main-config.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
When I start my TomCat server, an exception is catched :
[BlazeDS][ERROR] [Configuration] MessageBroker failed to start: Exception: flex.messaging.config.ConfigurationException: MessageBroker already defined from MessageBrokerServlet with init parameter messageBrokerId = '_messageBroker'
at flex.messaging.MessageBroker.registerMessageBroker(MessageBroker.java:1916)
COuld you help me please ?
Thank you very much,
Anthony
I believe you are loading the incorrect configuration file here...
<servlet>
<servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring-main-config.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
you have alreaded loaded /WEB-INF/spring-main-config.xml in the first few lines of the file
http://www.springbyexample.org/examples/simple-flex-webapp.html
This isn't really a Flex or BlazeDS issue, it's a more basic mis-configuration of Spring.
You're configured two separate Spring app-contexts, both with the same set of bean definitions (/WEB-INF/spring-main-config.xml).
The app-context defined by the <context-param> is the app-context associated with the webapp. The app-context defined by the ` is associated with the servlet.
Since you've given the same beans file to both, it'll instantiate and initialize the same set of beans twice, and the second time seems to be failing because the MessageBroker has already been defined.
You either need to break up your bean definitions into two sets, or just remove the first one, and just use the servlet context.

Resources