load one dispatcher servlet after another - spring

I have a scenario where we have two dispatcher servlet in our web.xml file.
One of the dispatcher servlet mentioned below have very minimal beans and starts quickly and pass health check and notifies the load balancer thats its ready to serve traffic.
<servlet>
<servlet-name>healthcheck</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:healthcheck.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet> here
The other dispatcher servlet is heavyweight and has lots of beans and takes almost 1~2 min to initialize.
we want to make sure the first dispatcher only sends a request to load balancer thats its ready to serve traffic once all the spring beans are initialized in the second dispatcher.
<servlet>
<servlet-name>content</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:content.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
some solution which i have on top of my head is
Let the content controller implements InitializingBean and in the afterPropertiesSet() method is fired set a flag as true and expose that as a JMX property.
The healthcheck controller will first check the property exposed as a jmx bean and only send signal to load balancer that its ready to server traffic only if the flag is true.
Is there a way i can defer loading of bean in healthcheck controller by like 2 min or so.
any advice ideas

Related

Difference between "dispatcherServlet" and "appServlet" in spring MVC

Difference between "dispatcherServlet" and "appServlet" in spring MVC. Can I get any samples or references?
Technically both are HttpServlet implementation to handle incoming requests. DispatcherServlet is Spring provided servlet implemenation having all essential features like exception handling ..
You have to just write your Request mappers ,it will handle all request.
AppServlet is nothing different, just your implementation for specific handling of requests.
Both will work in same way .If you dont have any specific handling than you can just go with Spring DispatcherServlet.
For example..
<servlet>
<servlet-name>DispatcherServlet</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
<!-- Custom Servlet -->
<servlet>
<servlet-name>CustomServlet</servlet-name>
<servlet-class>org.abc.CustomServlet</servlet-class>
<init-param>
<param-name>debug</param-name>
<param-value>false</param-value>
</init-param>
<init-param>
<param-name>any-other-Parameter</param-name>
<param-value>false</param-value>
</init-param>
<servlet-mapping>
<servlet-name>DispatcherServlet</servlet-name>
<url-pattern>*.do</url-pattern>
<url-pattern>/myapp/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>CustomServlet</servlet-name>
<url-pattern>/myapp2/*</url-pattern>
</servlet-mapping>
For reference of DispatcherServlet you can see http://www.mkyong.com/spring-mvc/spring-mvc-hello-world-example/
to understand this, you can have a look on below configuration :
<servlet>
<servlet-name>appServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/servlet-context.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
In above configuration DispatcherServlet is the servlet class provided by spring framework.
The job of the DispatcherServlet is to take an incoming URI and find the
right combination of handlers (generally methods on Controller classes)
and views (generally JSPs) that combine to form the page or resource
that's supposed to be found at that location.
while appServlet is the custom name given by you in your web.xml file.

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

Spring WS : Start Endpoint at startup

I'm using Spring WS to create WebService following by the link here
http://briansjavablog.blogspot.com/2013/01/spring-web-services-tutorial.html
And dynamic wsdl following by the setting here in web.xml
<servlet>
<servlet-name>webservices</servlet-name>
<servlet-class>org.springframework.ws.transport.http.MessageDispatcherServlet</servlet-class>
<init-param>
<param-name>transformWsdlLocations</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value></param-value>
</init-param>
<load-on-startup>0</load-on-startup>
</servlet>
I would like to ask is that possible to create Endpoint bean on startup time rather than waiting client to call on the endpoint url ?
Even if I set annotation #Lazy(false), Endpoint bean will be initialised only when client call to the web service address which I believe it's the normal behaviour. I'll use workaround solution by putting "curl" script to call url on deployment to make sure that every beans are initialised before making any request

How to make Spring MVC and plain JSP live together in one application

Say I have a Spring MVC application with JPA as backend. Now here we want to provide simple UI to user to perform simple configuration to some properties file. It would make sense to make it separate from the main Spring application because some configuration is related to Spring MVC so it will fail when start the main application by the main UI through Spring MVC.
But how to register both servlet(Spring and plain JSP)in the same web application?
<!-- Handles Spring requests -->
<servlet>
<servlet-name>SpringApplication</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/mvc-config.xml</param-value>
</init-param>
<load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>SpringApplication</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>PlainJSPApplication</servlet-name> <!--Is it ok to separate request to different servlet like this?-->
<servlet-class>com.app.plainJSP</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>PlainJSPApplication</servlet-name>
<url-pattern>/config</url-pattern> <!--How to handle mapping so not conflict to Spring main application-->
</servlet-mapping>
I think it is common to register another servlet class to in the SAME web.xml, is it OK? and also how to handle that request URL pattern, as "/" has been assign to Spring servlet?
Any advice would be appreciated.
You can separate Spring managed controllers and your own servlet by mapping both with different url patterns.
The requests for Spring controllers are managed by DispatcherServlet. Basically, it is just a Servlet that, when you map urls to it, it will automatically be seen by Spring, thus mapping it to the right controller, views etc.
web.xml
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>PlainJSPApplication</servlet-name> <!--Is it ok to separate request to different servlet like this?-->
<servlet-class>com.app.plainJSP</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>PlainJSPApplication</servlet-name>
<url-pattern>*.htm</url-pattern>
<url-pattern>*.html</url-pattern>
<url-pattern>*.bmk</url-pattern>
<!-- other url pattern ... -->
<!-- other url pattern ... -->
<!-- other url pattern ... -->
</servlet-mapping>
Here, all the requests end with .do will be seen by Spring. Others will then be seen by your servlets.
So, as long as you don't harm this mapping, Spring MVC & your normal servlets will integrate gracefully.

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.

Resources