I am trying to understand ApplicationContext hierarchies in spring.
I learned the following
An ApplicationContext cannot have
more than 1 parent
ApplicationContext.
When a given
ApplicationContext cannot resolve a
bean, it will pass on the resolution
request to its parent.
The parent of
an ApplicationContext is specified
in its constructor.
I would like to understand when to use ApplicationContext hierarchies (instead of a single ApplicationContext).
The best I could get from google was this. And what I understand is that if an application has a large number of beans defined at the various layers then each layer having its own ApplicationContext would be a benefit. What is not understood is what is the benefit of doing so and how is the benefit achieved?
The classic use-case for this is when you have multiple Spring DispatcherServlet within a single webapp, with each of these servlets having their own app context, but which need to share beans between them. In this case, you add a 3rd context at the level of the webapp, which is the parent of each of the servlet appcontexts.
You can take this pattern further, for example if you have multiple webapps bundled into a single JavaEE EAR. Here, the EAR can have its own context, which is the parent of the individual webapp contexts, which is the parent of the servlet contexts, and so on. You have this hierarchy of responsibility.
In other situations, the context structure is dictated by some other factor. For example, Spring Security is independent of Spring MVC, and requires its configuration beans to go in the webapp context. If you want to use Spring MVC with it, then the config for that has to go into the servlet context, which has the root webapp context as its parent.
Related
This question already has answers here:
application context. What is this?
(4 answers)
What is Application context and bean factory in spring framework [duplicate]
(1 answer)
Closed 3 years ago.
I have a Spring Boot app and it's running with Spring Data, MySQL, Spring Security and MVC. The app is running for me just as fine.
However, I keep hearing about ApplicationContext a lot and I was wondering when do I need to use it and would like to know what it does. Can someone give me an example and an overview of ApplicationContext and its use?
ApplicationContext is a core interface that Spring framework built on. If you're building a Spring application, you're already using the ApplicationContext. You can have great insight about this from Spring Framework Reference Documentation. As per this document, Spring framework consists with these modules;
The Context (spring-context) module builds on the solid base provided
by the Core and Beans modules: it is a means to access objects in a
framework-style manner that is similar to a JNDI registry. The Context
module inherits its features from the Beans module and adds support
for internationalization (using, for example, resource bundles), event
propagation, resource loading, and the transparent creation of
contexts by, for example, a Servlet container. The Context module also
supports Java EE features such as EJB, JMX, and basic remoting. The
ApplicationContext interface is the focal point of the Context module.
spring-context-support provides support for integrating common
third-party libraries into a Spring application context, in particular
for caching (EhCache, JCache) and scheduling (CommonJ, Quartz).
Spring ApplicationContext also inherits BeanFactory super-interface. So technically ApplicationContext is capable of doing all the things, BeanFactory interface is capable and much more. BeanFactory interface along with ApplicationContext provide the backbone of the Spring IoC container (Core container). Which is Bean management for your application.
The interface org.springframework.context.ApplicationContext
represents the Spring IoC container and is responsible for
instantiating, configuring, and assembling the aforementioned beans.
The container gets its instructions on what objects to instantiate,
configure, and assemble by reading configuration metadata. The
configuration metadata is represented in XML, Java annotations, or
Java code. It allows you to express the objects that compose your
application and the rich interdependencies between such objects.
ApplicationContext uses eager loading mechanism. So, every bean declared in your application, initialize right away after the application started and after, this ApplicationContext scope is pretty much read-only.
Initiate a Spring IoC container with custom bean definitions is pretty much staright forward.
ApplicationContext context = new ClassPathXmlApplicationContext(new String[] {"daos.xml"});
Following file shows this daos.xml file content;
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="accountDao"
class="org.springframework.samples.jpetstore.dao.jpa.JpaAccountDao">
<!-- additional collaborators and configuration for this bean go here -->
</bean>
<bean id="itemDao" class="org.springframework.samples.jpetstore.dao.jpa.JpaItemDao">
<!-- additional collaborators and configuration for this bean go here -->
</bean>
<!-- more bean definitions for data access objects go here -->
</beans>
After that you can access the beans define in the .xml like this;
JpaItemDao obj = (JpaItemDao) factory.getBean("itemDao");
These instances are now being initialized and managed by the ApplicationContext. But most users prefer to use #Bean annotation define beans to do the binding and #Autowired annotation to do the dependency injection. So, no need to manually feed a bean .xml to custom initialized ApplicationContext.
#Configuration
class SampleConfig {
#Bean
public JpaItemDao getJpaItemDao() {
return new JpaItemDao();
}
}
and inject in;
#Component
class SampleComponent {
#Autowired
private JpaItemDao itemDao;
public void doSomething() {
itemDao.save(); // Just an example.
}
}
Besided the bean management, ApplicationContext does some other important thing in the Spring core container. As per ApplicationContect javadoc, they are;
Bean factory methods for accessing application components. Inherited from ListableBeanFactory.
The ability to load file resources in a generic fashion. Inherited from the ResourceLoader interface.
The ability to publish events to registered listeners. Inherited from the ApplicationEventPublisher interface.
The ability to resolve messages, supporting internationalization. Inherited from the MessageSource interface.
Inheritance from a parent context. Definitions in a descendant context will always take priority. This means, for example, that a
single parent context can be used by an entire web application, while
each servlet has its own child context that is independent of that of
any other servlet.
Also, checkout the sub-interfaces of ApplicationContext that specifically designed for work on different use cases like WebApplicationContext.
ApplicationContext is a core concept (arguably the most important one) of spring used also in spring boot of course but and ideally hidden from the programmers in both cases, meaning that the programmer should not directly interact with it in a business code of the application.
Technically its an interface that has many implementations, the relevant one is picked depending on in which environment you're running and how do you configure the application.
So does it do? Its a class that basically is a registry of all the beans that spring has loaded. In general, starting up the spring mean finding the beans to load and putting them in the application context (this is relevant for singletons only, prototype-scopes beans are not stored in the ApplicationContext).
Why does spring need it?
For many reasons, to name a few:
To manage lifecyle of the beans (when the application shuts down, all beans that have a destroy method should be called)
To execute a proper injection. When some class A depends on class B spring should inject class B into class A. So by the time of creating the class A, class B should already be created, right? So spring goes like this:
Creates B
Puts B into application context (registry)
Creates A
For injection goals: gets B from the application context and injects into A
// an illustration for the second bullet
class B {}
class A {
#Autowired
B b;
}
Now there are other things implemented technically in application context:
Events
Resource Loading
Inheritance of application contexts (advanced stuff, actually)
However now you have an overview of what it is.
Spring boot application encapsulates the application context but you can still access it from many places:
in the main method when the application starts it returns an application context]
you can inject it into configuration if you really need
its also possible to inject the application context into the business bean, although we shouldn't really do so.
In simple words:
Spring is popular for dependency Injection.
So all the bean definitions(Objects) will be created by the spring and maintained in the container. So all the bean life cycle will be taken care by spring container.
So ApplicationContext is a interface It has different implementations will be there to initialize the spring container.
So ApplicationContext is the reference to Spring Container.
Some popular implementations are:
AnnotationConfigWebApplicationContext,
ClassPathXmlApplicationContext,
FileSystemXmlApplicationContext,
XmlWebApplicationContext.
Reference: https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/context/ApplicationContext.html
I am new to spring. I wanted to know two things :
Does the Dispatcher Servlet and ApplicatonContext exists in two different containers (in terms of spring).
Also, if they are part of same container, then how is it possible that spring is creating two beans if I scan the classes in both of their config files?
Will be very thankful for any help.
SpringMVC has one Container i.e WebApplicationContext(Interface)
A Context represents your environment. It represents the state surrounding where you are in your system. For example, in web programming in Java, you have a Request, and a Response. These are passed to the service method of a Servlet. A property of the Servlet is the ServletConfig, and within that is a ServletContext. The ServletContext is used to tell the servlet about the Container that the Servlet is within. So, the ServletContext represents the servlets environment within its container. Similarly, in Java EE, you have EBJContexts that elements (like session beans) can access to work with their containers.(copy/paste from qoura)
I was referring to Spring configuration related blogs and came across some information on applicationContext. One article it is mentioned:
"In most simple cases, the ApplicationContext(defaule name for file is applicationContext.xml) is unnecessary. It is generally used to contain beans that are shared between all servlets in a webapp. If you only have one servlet, then there's not really much point, unless you have a specific use for it."
Where it is also mentioned:
"If you are not explicitly declaring the context configuration file name in web.xml using the contextConfigLocation param, Spring will search for the applicationContext.xml under WEB-INF folder and throw FileNotFoundException if it could not find this file."
Above two statements seems to be contradicting (though it is not). Can you please help clarifying above or suggests me link that clarifies above points?
From : http://www.tutorialspoint.com/spring/spring_applicationcontext_container.htm
The Application Context is spring's more advanced container.
Similar to BeanFactory it can load bean definitions, wire beans together and dispense beans upon request.
Additionally it adds more enterprise-specific functionality such as the ability to resolve textual messages from a properties file and the ability to publish application events to interested event listeners. This container is defined by the org.springframework.context.ApplicationContext interface.
That means Application Context is a container and it can load beans from xml files and from #Bean annotations from your java code. With recent spring versions you can configure all of your beans in java code and not use xml files.
I have learned how to configure spring MVC without web.xml and .xml files for parent and child context from this link. I saw how to programmatically make context hierarchy in the official spring docs as follow.
ApplicationContext parent = new GenericXmlApplicationContext(ParentAnnotationConfig.class);
GenericApplicationContext child = new GenericApplicationContext(parent);
But the post from the link don't have similar statements like above ones. Does this code make context hierarchy between two context or not?
The code from the link you submitted uses Spring MVC. The programmatic method you show is independant of Spring MVC. It makes a big difference.
Spring MVC automagically creates parent child relations between the root context and the dispatcher servlet context(es). The wepapp should have :
one single root context referenced in the ServletContext. It is supposed to be used for everything not directly related to the servlet : model, persistance and filters that can exist independantly of the servlet
one context per dispatcher servlet constructed with the root context as parent. It is supposed to be used for controllers, views, interceptors
The parent-child relation ensure that you can access all beans from the controllers, but you cannot access web (servlet) beans from root contex.
To directly answer your question, I would say that the linked code does not explicitely build the context hierachy. The hierarchy is built by Spring MVC framework. So it does exist, and you must not try to generate it explicetely.
From XmlWebApplicationContext javadoc:
By default, the configuration will be taken from "/WEB-INF/applicationContext.xml" for the root context, and "/WEB-INF/test-servlet.xml" for a context with the namespace "test-servlet" (like for a DispatcherServlet instance with the servlet-name "test").
What does it mean a Spring context?
What is the root context? What other kinds of Spring context are there?
What is a namespace?
UPDATE:
Some follow-up questions:
What is a Spring ApplicationContext - is it some "thing" that holds the beans that are defined in a configuration XML file?
Looking at the code of ContextLoaderListener, it looks like it loads the data defined in the config XML file(s). But my Spring web app works without defining this listener or any other listener. How could it be?
In what scenarios would it make sense to have more than one instance of Spring's DispatcherServlet?
Is the root context (data from applicationContext.xml) applicable to every instance of DispatcherServlet, while other contexts (e.g. data from test-servlet.xml) applicable only to the relevant DispatcherServlet (i.e. test)?
"Spring context" = a Spring ApplicationContext.
"root context", in terms of a web application, means the main context that's loaded and used by the webapp. Typically, you'll start the root context with a ContextLoaderListener.
The root context isn't really a "kind" of context. It's just a role that a context plays. You have one root context in a webapp. Other contexts are not the root context. They're usually children of the root context.
A namespace here refers to the scope of an instance of Spring's DispatcherServlet. All it's saying right there is that if you name your servlet "test" in your web.xml, then by convention, Spring will look for a file named "test-servlet.xml" to use as that dispatcher's context. Incidentally, each context like this which is created for a dispatcher becomes a child of the root context.
Edit: To answer your new questions:
Follow the link in the first line of my answer to learn about the ApplicationContext. If you have questions not answered there, I'd suggest posting a new SO question.
The root context is optional. If you don't have the ContextLoaderListener defined, then you just don't have a root context. When you use a DispatcherServlet, it starts its own ApplicationContext, and it will get the beans it needs from there.
I don't know of one off the top of my head. I suppose if there were a need for drastically different configurations between some of the URL resources in your app, that might drive you to do it.
Yes. To state it in the proper terms, the root context is the parent context of any context started for a DispatcherServlet. Beans in a parent context are accessible through and by the child context, but the reverse isn't true.
In a web application, the architecture is usually divided into layers like the popular MVC structure.
So a web app comprises basically of a layer that handles the client requests i.e HTTPRequests
and a layer that services those requests .
To summarize : classes that are meant to handle the Http requests i.e the controllers which are mapped to urls come under the test-servlet.xml. This is called as WebapplicationContext containing only the beans that are required mainly to handle the client requests.
Now the next part is the Service/Dao layer that comprises of your business logic. Beans that perform such logic are loaded under ApplicationContext object.
Now you may ask why have they separated these things in to files or two different objects.
Its because, an application have the same business logic that can be used by multiple clients working on different protocol. You may use the same service layers to handle RMI as well as HTTP calls.
So Spring created a parent context that is started us as an ApplicationContext. And then if your applicationhandles web requests, you can create a dispathcher servlet which has its own Webapplicationcontext and initialized as a child of the parent context.
So all the parent beans can be referenced in the child and can be overiden but not vice versa