Context Level in Spring Web Application Architecture - java

I am struggling with Architecture level of Spring web application, Below I am making my pointers. Please help regarding the below:
Context Level Programing: Servlet Context and Root Application Webapplication context and Web Application context.
I don't know which bean needs to mention on which level.
What is the Hierarchy level of Context in Spring Web Application. which comes upper or lower.
Which context is under which context.
My Understanding is Servlet Context is the object of Servlet Container(tomcat container), and Servlet container is responsible to manage all the servlet, where all servlet lives.
All Bean dependecies Lives in Application container, and root web application context is the object of Application Container.
Every servlet have its own web application context, i don't know what is this, is it same as Servlet context.
4. And Relation between them?
Please describe it with help of diagram like this, (It will be really appreciable)
This is just example to understand which loads first and what is inside what.
Please check this reference diagram

Think of context as a component's execution environment.
A servlet container (Web server), hosts web applications and on startup it creates one ServletContext for each of these applications. So each web app lives in a servlet context which provides to it information about its environment (container). This is Java Servlet API. Tomcat is an implementation of this API.
Now, Spring is one of the frameworks we can use to create web apps. When we deploy our web app in the container, it (container) will create a ServletContext and this is where our app will live in.
Each Spring application has a root context (ApplicationContext) and in it one or more child contexts can exist. WebApplicationContext extends ApplicationContext. There can be many WebApplicationContexts, children of the root context of an application. The WebApplicationContext (which adds a method, getServletContext() ) is able to work with the ServletContext in which it lives.
So in a spring based web app deployed in a container:
container --contains 1..n--> ServletContext --contains 1--> ApplicationContext --contains 1..n--> WebApplicationContext

Related

Why can't java webapps have 2 webcontexts?

A java webapp must choose between either static context or "webcontext". Why do we need a webcontext just for a web server like jetty and why must we route everything to the same "webcontext" ?
Because Jetty is a JEE servlet container and in the JEE world there is a one to one relationship between a webapplication and the web context. The intention is to be able to run several independent webapplications within the same servlet container. So it is easy to route to the appropriate webapplication by the first part of the URL path.
Theoretically it would be possible to declare more than one webcontext for a webapplication but it is specified otherwise. See section 10.2 "Relationship to ServletContext" in Java Servlet Specification 3.1:
The servlet container must enforce a one to one correspondence between
a Web application and a ServletContext. A ServletContext object
provides a servlet with its view of the application.

How is Spring actually bootstrap?

Does anybody know how Spring is actually bootstraps?
Which instances created and by whom?
I really want to know who creates instances of WebApplicationContext and ContextLoader. Is it work of Tomcat?
Servlet context listener (web.xml) approach
A web application WAR is being deployed by user.
Servlet container (Tomcat) reads web.xml.
Servlet context listener ContextLoaderListener is being instantiated (if defined as <listener> inside the web.xml) by servlet container.
ContextLoaderListener creates new WebApplicationContext with application context XML configuration.
Your ROOT context beans are registered and instantiated by BeanFactory inside the application context.
DispatcherServlet is being instantiated by servlet container.
DispatcherServlet creates its own WebApplicationContext (WEB-INF/{servletName}-servlet.xml by default) with the ROOT context as its parent.
Your servlet beans are registered and instantiated by BeanFactory inside the application context.
DispatcherServlet registers some default beans in case you did not provide them yourself.
Servlet container initializer (non web.xml) approach
This one is possible with Servlet 3 features.
A web application WAR is being deployed by user.
Servlet container searches for classes implementing ServletContainerInitializer via Java's ServiceLoader.
Spring's SpringServletContainerInitializer is found and instantiated by servlet container.
Spring's initializer reads web application's class-path and searches for WebApplicationInitializer implementations.
Your WebApplicationInitializer is found (btw. check its JavaDoc!!!) and instantiated by SpringServletContainerInitializer.
Your WebApplicationInitializer creates new ROOT WebApplicationContext with XML or #Configuration based configuration.
Your WebApplicationInitializer creates new servlet WebApplicationContext with XML or #Configuration based configuration.
Your WebApplicationInitializer creates and registers new DispatcherServlet with the context from previous step.
Servlet container finishes the web application initialization and instantiates components which were registered by their class in previous steps (none in my example).
Java based approach is much more flexible. You can leave the context creation to DispatcherServlet or even the whole instantiation of DispatcherServlet itself to servlet container (just register servlet DispatcherServlet.class instead of its instance).
See http://docs.spring.io/spring/docs/4.0.x/spring-framework-reference/htmlsingle/#context-create.
The principle is to declare a ServletContextListener in the standard webapp descriptor (web.xml). Such a listener is indeed instantiated by the container and is called when the application is initialized and when it's destroyed.
Spring provides such a ServletContextListener: ContextLoaderListener which, as its name indicates, loads a Spring context when the webapp is initialized.

Why does Spring MVC need at least two contexts?

In Spring MVC, there are two contexts. One is the application context or global context which is booted up by ContextLoaderListener. It takes all the configuration files mentioned in contextConfigLocation parameter.
Now if you are using Spring MVC as well, then Dispatcher servlet is required, which boots up another container which is also known as web application container. This container takes the global container as a parent.
When integrating struts1 with spring, there is only one context. Why does spring mvc need two? Is it possible to use only one context when using spring mvc?
thanks!
Having a root web application context plus a child servlet context is just an option. If you know that your application won't have a second servlet, it's arguably simpler to have one single Spring context for the whole web application.
You can achieve that setup by simply removing the ContextLoaderListener (and the accompanying contextConfigLocation context-param) from your web.xml and moving all bean definitions into the xml defining the servlet context ([servlet-name]-servlet.xml).
This is possible, because the FrameworkServlet (super-class of DispatcherServlet) doesn't care if there is a root application context when creating the servlet context. It just relays the root context as the parent if available. See related code here.
Imagine you had two separate Dispatchers, each serving a different purpose, and each having its own dependencies. You would configure those independently using separate contexts.
If there is any shared configuration, this can go in the 'global' context.
I don't think it's possible to have only one context using DispatcherServlet, as it creates its own context and links it to the parent context (via the FrameworkServlet superclass).
FrameworkServlet.createWebApplicationContext
Check this answer About multiple containers in spring framework
Yes ,you can have one context only.
For code reuse it would be better to isolate services in Application Context rather then WebApplicationContext.but this not compulsion.you can keep only webApplicationcontext only.

How to retrieve Spring context loaded in Tomcat from outside application

I'm trying to do the following:
Imagine you have a Java EE application running on Tomcat using Spring as the IoC engine.
I have another jar in the application that has full access to all the resources. i.e. I can instantiate the same application context that is running in tomcat but it takes around 30 seconds to instantiate all the dependencies.
Anyone knows if it is feasible to retrieve current tomcats ApplicationContext from the outside?
There is a way to ask for the WebApplicationContext inside a servlet but I'm not on it, I only have a jar with a main method.
No. You have to be running within tomcat (a webapp) to be able to access the servlet context (and from there - the application context). You are not even in the same runtime with the main method.
If you want to get some information from the context, you should expose it as a service. For example:
a restful service, via Spring-MVC
via JMX
via JNDI

Accessing beans in portlet specific context programmatically

I have a portlet application. It is configured using Spring framework IoC container. I am using org.springframework.web.context.ContextLoaderListener to load my context.
I have an application context at root level (applicationContext.xml) and a portlet specific context (MyPortlet-portlet.xml).
I have a portlet of type org.springframework.web.portlet.DispatcherPortlet which is wired up to a Controller. In the Controller I want to access one of the beans (e.g. bean with id "myBean") I have defined in my portlet specific context. I have tried
MyBean mybean = (MyBean)PortletApplicationContextUtils.getWebApplicationContext(
getPortletContext()).getBean("myBean")
However only the beans in my application context are available here - none of my beans in my portlet specific context are available.
Is there a way to access the beans in my portlet specific context?
Thanks
Firstly, can't you just wire in the bean to your controller in the normal way, rather than retrieving it programmatically?
Failing that, you should realise that getWebApplicationContext() gets a reference to the root webapp context, not the servlet app context:
Find the root WebApplicationContext
for this portlet application, which is
typically loaded via
ContextLoaderListener or
ContextLoaderServlet.
If your controller needs a handle on its own context, then it should implement ApplicationContextAware or BeanFactoryAware, or it can use #Autowired ApplicationContext if you want to use autowiring.

Categories

Resources