I am a newbie and going through spring learning curve and i have a question to understand what cases i will be using code based servlet container initialization against xml initialization in web descriptor file.
The reason for my question is, at this time i wanted to spend time in learning what is used most of the time rather overloading many concepts which might be provided with the framework just for flexibility.
Any advice?
Thanks for reading
The main reason you'd want to use Java based container initialization is when you want to register Spring managed Servlet, Filter, and XxxListener objects.
For example, when you want to register a ServletContextListener, you specify
<listener>
com.your.listeners.MyListener
</listener>
in the deployment descriptor. The container takes that fully qualified class name and uses reflection to find the corresponding Class object which it instantiates to get an instance. In other words, the object is uniquely managed by the container. You can't have Spring inject fields easily.
On the other hand, with a ServletContainerInitializer, or the corresponding Spring class, you can specify Servlet, Filter, or Listener beans in your Spring context (either through XML or #Configuration classes) and register those Spring-managed instances directly through the ServletContext.
Note that there are still some configurations for which you need to use the deployment descriptor.
Related
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'm a noob when using Spring and I have a doubt.
When and where must I initialize the spring context?
Right now I am initializing the context when I'm going to use something like a properties file:
ClassPathXmlApplicationContext cxt = new ClassPathXmlApplicationContext("myContext.xml");
But I have read that the Spring context must be initialized in the entry point of my program (Main.java) and pass it as argument in the necessary methods.
Is this true?
As #MarounMaroun said, it really depends on what are you trying to do.
When people use Spring they usually build the entire application to take advantage of what Spring has to offer. That is to say, they put everything in the Spring context, configure it, and let it wire all the things together when starting. So in order to be useful, the application needs to load the Spring context before doing anything else.
For a standalone application you do the initialization in the main method.
When main is called, you first initialize the Spring context, and once the context is fully loaded you retain a reference to it and make it available where needed.
If it makes sense to initialize the Spring context at a later time or in another class you can do that too, but as I said, most applications need the context initialized to be able to function so that's why they initialize it as early as possible, in the main method, and that's probably the recommendation you have read.
If you are talking about a web application, you should do it web.xml
Loading context in Spring using web.xml
If it's a test, things are different:
spring junit load application context for tests
In both cases, you don't need an explicit main.java
When i want a bean say in the main method I ask for a getBean on the id. Does spring container do the same when we define properties as refs to other beans within a single bean ?
Does spring container do the same when we define properties as refs to
other beans within a single bean
Ultimately yes, Spring does find beans within the application container which match your bean definition. How it does it is something which shouldn't be too much of a concern to most users. Since it's usually enough to know that if you ask for a bean from Spring it'll come wired with all of it's dependencies.
If you're interested in the exact wiring mechanism the source code is the place to learn.
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