Using global scope in spring mvc - java

I came across below statement from Spring MVC documentation:
Upon initialization of a DispatcherServlet, Spring MVC looks for a
file named [servlet-name]-servlet.xml in the WEB-INF directory of
your web application and creates the beans defined there, overriding
the definitions of any beans defined with the same name in the global
scope.
Please help me in understanding this statement.
As global scope is used for portlet based applications, then why a developer wants to configure like this in normal Spring MVC applications?

I don't think the term "global scope" here means the global scope bean like singleton, prototype, request, session and global. I believe the global scope here means the scope of the bean context.
In Spring MVC, there are 2 scopes of bean can be defined. The first one is at servlet context level which I believe is what it meant by "global scope" in the above statement. The second one is at servlet level where the bean defined at this level will take priority when resolved by other bean in servlet level.
The beans in servlet level will be able to resolve beans in servlet context (global) level but not the other way round.

Spring MVC provides options to configure multiple Context based on number of DispacthServlet Configuration .
For example
Consider you have two modules with in your application and url pattern starts as module1/* and module2/* . And you want to keep two different context ( always declarations in *context.xml is private to the context ). So you would be creating two dispatchServlet and provide two different servletname and url pattern. Now you have two Spring context which has specific declartions and which is not visible to other. But still you may wanted to declare some application wide beans such as persistentManager / Logger instance and so. for those case you can keep seperate config as root-context.xml and keep the generic declartions in that root. Which is considered here as "GLOBAL SESSION" Now this Global Session beans scope can be different scope based on configuration. And the bean configured in Global Session ( root-context) can be overriden by specific-servlet for customization.
I like the answer provided here also Understanding contexts in Spring MVC

A typical Spring MVC application will have two contexts: the root context and the servlet context.
The root context is loaded by the ContextLoaderListener. The ContextLoaderListener loads the ApplicationContext and sets it as an attribute in the ServletContext. This makes it available to other Servlet, Filter, and XxxListener instances.
The servlet context is another ApplicationContext loaded by the DispatcherServlet when its init() method is called. Since the init() method of a Servlet is called after the contextInitialized() method of a ServletContextListener is called, the DispatcherServlet has access to the root context set as an attribute in the ContextLoaderListener and can therefore use the beans declared there.
[...] creates the beans defined there, overriding the definitions of any
beans defined with the same name in the global scope.
A bean definition is, for example,
<bean id="someBean" class="com.company.SomeBean">
<property name="someProp" value="some value" />
</bean>
Spring creates a BeanDefinition object for this and all other <bean> declarations (or #Bean annotation methods). When the ApplicationContext is refreshed, Spring generates actual instances from these bean definitions.
What the above quote from the documentation is saying is that if you have a <bean> declaration with the same name or id in both the root context and the servlet context, the servlet context one will overwrite the root context one.

Related

difference between ContextLoader and ContextLoaderListener

the difference between ContextLoader and ContextLoaderListenerI am not understanding the difference. I have tried to search on google but I am not able to search. Please help me on this.
Performs the actual initialization work for the root application context. Called by ContextLoaderListener and ContextLoaderServlet.
Regards a "contextClass" parameter at the web.xml context-param level, falling back to the default context class (XmlWebApplicationContext) if not found. With the default ContextLoader, a context class needs to implement ConfigurableWebApplicationContext.
Passes a "contextConfigLocation" context-param to the context instance, parsing it into potentially multiple file paths which can be separated by any number of commas and spaces, like "applicationContext1.xml, applicationContext2.xml". If not explicitly specified, the context implementation is supposed to use a default location (with XmlWebApplicationContext: `
Note: In case of multiple config locations, later bean definitions
will override ones defined in earlier loaded files, at least when
using one of Spring's default ApplicationContext implementations. This
can be leveraged to deliberately override certain bean definitions via
an extra XML file.
https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/context/ContextLoader.html

What is the difference between spring parent context and child context?

I was reading spring doc the core container I want to understand the purpose of ref parent when inject collaborators then I found this notion of parent context child context or parent container and current container this is the part that I'm confuse about it :
This part of doc
Specifying the target bean through the parent attribute creates a
reference to a bean that is in a parent container of the current
container. The value of the parent attribute may be the same as either
the id attribute of the target bean, or one of the values in the name
attribute of the target bean, and the target bean must be in a parent
container of the current one. You use this bean reference variant
mainly when you have a hierarchy of containers and you want to wrap an
existing bean in a parent container with a proxy that will have the
same name as the parent bean.
<!-- in the parent context -->
<bean id="accountService" class="com.foo.SimpleAccountService">
<!-- insert dependencies as required as here -->
</bean>
<!-- in the child (descendant) context -->
<bean id="accountService" <!-- bean name is the same as the parent bean -->
class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="target">
<ref parent="accountService"/> <!-- notice how we refer to the parent bean -->
</property>
<!-- insert other configuration and dependencies as required here -->
</bean>
can someone give me some help or an example of this two type of context ? and what is the purpose of the ref parent Thank you in advance
The beans of the Spring run inside an application context.
The Application Context is Spring's 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 org.springframework.context.ApplicationContext interface.
https://www.tutorialspoint.com/spring/spring_applicationcontext_container.htm
For each application context you can have many configuration files, configuration classes or a mix of both.
You can create an application context with a code like this:
ApplicationContext context = new FileSystemXmlApplicationContext("Beans.xml");
And obtain the beans with context.getBean or with #autowired.
There are some cases when you want(or need) to have a context hierarchy. In these cases Spring provides a way of specifying a parent context. If you look at this constructor, you will see that it receives a context parent.
http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/context/support/FileSystemXmlApplicationContext.html#FileSystemXmlApplicationContext-org.springframework.context.ApplicationContext-
As you can see the parent context is the same type of a child context, they both are http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/context/ApplicationContext.html.
The difference is that they are related through a parent/child relationship. Not a compose(import) relationship.
The most common case where you see this is in a Spring MVC application, this applications have 2 context, the first is the dispatcher servlet context and the other one is the root context.
Here you can see the relationship
http://docs.spring.io/spring/docs/3.0.x/spring-framework-reference/html/mvc.html#mvc-servlet
And here you can see an example of application context hierarchy in spring boot applications.
https://dzone.com/articles/spring-boot-and-application-context-hierarchy

Spring default-lazy-init does not seems to work, i see Pre-instantiating of singletons

I am defining default-lazy-init="true" in the spring context file inside beans tag but when I start tomcat, I see my beans are getting instantiated. here is what it shows in log -
org.springframework.beans.factory.support.DefaultListableBeanFactory (DefaultListableBeanFactory.java:555) - Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory#ac6fb1: defining beans [dataSource,my other beans in app.......
Am I missing something ?
Even if a bean is declared to be lazy initialized, it will still be initialized if another bean depends on it.
I'm going to assume from your log, that the bean in question is dataSource. I will also assume you have other beans that depend on dataSource (otherwise it wouldn't be very useful). If the context initializes the other beans and finds that, for example, it needs to autowire the dataSource bean, it will have to first initialize it.
If you want full lazy initialization, you will have to make every bean in some object graph be lazily initialized.

Spring Injection & Globally initialized objects

I have a spring injected service
class A{
List l = new ArrayList();
public m1(){
//do some additions in list
}
public m2(){
//do some new additions in list
}
}
Now because creating of objects of A, is in the hands of spring the behavior of program is not what is expected. (I expect list to be available empty always but not initialized by methods for some wired reason)
Will Spring always create only one instance of A, so that list l will keep on growing, I have configured bean as singleton in application context.
If yes, naturally I must initialize the list inside the functions m1 & m2 or callee must past the reference, and in my case callee being struts2 actions they are not singleton so this issue can be solved?
Or
Does spring provide any support in configuration to initialize member variables at every call or something else?
More generally what are best practices to have in writing services injected by spring about using member variables/ local variables for performance & efficiency.
Trying to answer following :
Does spring provide any support in configuration to initialize member variables at every call or something else?
By default Spring beans are singleton. Initialized only once and use the same object again and again.
However, if requirement changes as you asked. You need to understand scope attribute provided by the Spring.
<bean id="id" class="com.test.TP" scope="prototype">
</bean>
Refer following for detail understanding.
Scope Description
singleton
Scopes a single bean definition to a single object instance per
Spring IoC container.
prototype
Scopes a single bean definition to any number of object instances.
request
Scopes a single bean definition to the lifecycle of a single HTTP
request; that is each and every HTTP request will have its own
instance of a bean created off the back of a single bean definition.
Only valid in the context of a web-aware Spring ApplicationContext.
session
Scopes a single bean definition to the lifecycle of a HTTP Session.
Only valid in the context of a web-aware Spring ApplicationContext.
global session
Scopes a single bean definition to the lifecycle of a global HTTP
Session. Typically only valid when used in a portlet context. Only
valid in the context of a web-aware Spring ApplicationContext.
http://static.springsource.org/spring/docs/3.0.0.M3/spring-framework-reference/html/ch04s04.html
It is also possible to have user defined scope such as thread scope.
You can configure your bean as follows:-
<bean id = "serviceBeanA" class = "somepkg.A" scope="prototype">
<property name = "l">
<value>
<list>
<value>ABC</value>
.....
</list>
</value>
</property>
</bean>
I'm not sure if I understand the question but your sample class should work fine with spring. Spring will call the default constructor unless you pass in constructor args in the configuration file. As long as you have an id="..." in the bean then it will create a singleton of that class. Then, the first class that calls a.m1() will see l as being an empty list.
What may be happening is that you have multiple instances of A being created. See here about Spring singletons versus non. To quote:
Beans are defined to be deployed in one of two modes: singleton or non-singleton. (The latter is also called a prototype, although the term is used loosely as it doesn't quite fit). When a bean is a singleton, only one shared instance of the bean will be managed and all requests for beans with an id or ids matching that bean definition will result in that one specific bean instance being returned.
So if you don't have an id or name specified in your Spring configuration then you might get multiple instances of A created.
The non-singleton, prototype mode of a bean deployment results in the creation of a new bean instance every time a request for that specific bean is done. This is ideal for situations where for example each user needs an independent user object or something similar.

Spring 3 Dependency Injcetion

I am using Spring3 with xml based configuration.
The problem is when the IOC container starts it loads/caches all the properties/fields defined in com.dao.MyDAOFactory class. I want to tell spring that only load/cache specific properties/fields.
The bean declaration is given below
<bean id="daoFactory" class="com.dao.MyDAOFactory" ></bean>
Can any one help me ?
You can use the lazy-init attribute to defer the loading of your beans, but eventually all of them will be loaded.
Also keep this in mind that if a non-lazy singleton bean depends on one or more lazy beans, the lazy beans will be loaded at startup.

Categories