wood burning stoves 2.0*
The moose likes Spring and the fly likes Spring - Multiple IoC Containers with Singleton Bean in a JVM Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Android Security Essentials Live Lessons this week in the Android forum!
JavaRanch » Java Forums » Frameworks » Spring
Bookmark "Spring - Multiple IoC Containers with Singleton Bean in a JVM" Watch "Spring - Multiple IoC Containers with Singleton Bean in a JVM" New topic
Author

Spring - Multiple IoC Containers with Singleton Bean in a JVM

Perry Terrance
Ranch Hand

Joined: Oct 02, 2009
Posts: 55
I know that one of the key principals of Spring is that the Spring meta-data (in my case the XML config files) have to be loaded "somehow" - whether by direct explicit code, web.xml, etc...

However I always wondered about the whole common Singleton aspect of these Spring beans and the IoC container itself in a JVM.

The Spring Beans don't get loaded into the JVM until the IoC Container is called in the first place right?


So for example:

My Spring config has a Bean called "myBean1" inside a Spring config file called "spring-config.xml."

I use ApplicationContext called "IoCContainer1" to create my first IoC container instance from "spring-config.xml." And then I do a getBean "myBean1" with "IoCContainer1."

Now if in the same running instance, I create another IoC container through ApplicationContext called "IoCContainer2" from the same "spring-config.xml" - and I then do a getBean "myBean1" with "IoCContainer2."

Are both Spring Beans I can called of "myBean1" the same exact instance in the JVM - even if the IoC are two separate instances?

Or is Spring smart enough to know after the initial Bean is created - any other calls to it (even from newly made IoCContainers such as "IoCContainer2","IoCContainer3","IoCContainer4",etc) are the same exact Bean instance?
Saifuddin Merchant
Ranch Hand

Joined: Feb 08, 2009
Posts: 597

I sure you could try it out pretty easily

If you've looking for a 'guess' I would say each IOC container would be separate beans, I don't see why spring should be merging "beans" from different containers unless its explicitly designed to do something like that (e.g. WEB-Application context -- a single root context per application, while each servlet in the application has its own child context)


Cheers - Sam.
Twisters - The new age Java Quiz || My Blog
Perry Terrance
Ranch Hand

Joined: Oct 02, 2009
Posts: 55
Sam Mercs wrote:I sure you could try it out pretty easily

If you've looking for a 'guess' I would say each IOC container would be separate beans, I don't see why spring should be merging "beans" from different containers unless its explicitly designed to do something like that (e.g. WEB-Application context -- a single root context per application, while each servlet in the application has its own child context)


So if I understand you correctly:

Is that in my Spring XML configuration even if I had set all my Spring Beans to "Singleton" mode (which I believe is the most common Spring Bean configuration for most setups), these Spring Beans will only act as "Singletons" within the context of that specific instantiated IoC container?

It's not defined as a strictly universal Java Singleton for the entire running JVM - as I can have those same-sourced Spring Beans running in multiple instances in each of those individually instantiated IoC containers?

Is that correct?
Saifuddin Merchant
Ranch Hand

Joined: Feb 08, 2009
Posts: 597

Yes I believe so.

I like to mention that spring does not support the concept of GOF singleton - which is one Object of a class no matter what.
Spring singleton are simple one Object per bean definition, so in a spring context you can have,



In this case you would have two objects of the same class Customer within the same VM and same Application context. A true singleton - would never allow two objects of its type to exists!

Spring singleton are per bean defined per context.
Perry Terrance
Ranch Hand

Joined: Oct 02, 2009
Posts: 55
So in your previous example, you were calling specifically two Spring Beans made from the same class. Thus they would be independent from one another when initialized in the JVM.

Going back to my original example, I was doing getBean calls from a "single" Spring Bean (myBean1), but from multiple instantiated IoC container (IoCContainer1 and IoCContainer2).

Either way, I guess both methods create individuality of the created entities....

So from all this, for a Spring Bean "Singleton" to work, Spring not only has to call from the same Bean ID (eg calling the same "customer1" and only that), it also has to all be done within the same process of that instanitated IoC Container instance.

Is that correct?
Saifuddin Merchant
Ranch Hand

Joined: Feb 08, 2009
Posts: 597

Yes that is correct. The spring document on the Singleton scope sums it up pretty well - you might want to have a look

http://static.springsource.org/spring/docs/3.0.0.M3/spring-framework-reference/html/ch04s04.html#beans-factory-scopes-singleton

Here's a quote from the documentation,
Please be aware that Spring's concept of a singleton bean is quite different from the Singleton pattern as defined in the seminal Gang of Four (GoF) patterns book. The GoF Singleton hard codes the scope of an object such that one and only one instance of a particular class will ever be created per ClassLoader. The scope of the Spring singleton is best described as per container and per bean.


If you need a true singleton you need to do it the old fashioned way - private constructor, a static getInstance method and code to handle serialization if you implement serializable.
Perry Terrance
Ranch Hand

Joined: Oct 02, 2009
Posts: 55
So I just started getting into the MVC-side of Spring and been wondering how this IoC Container concept works with web.xml (WEB-Application context) and in terms of Servlets turned Controller by Spring MVC.

As Sam mentioned before:

If you've looking for a 'guess' I would say each IOC container would be separate beans, I don't see why spring should be merging "beans" from different containers unless its explicitly designed to do something like that (e.g. WEB-Application context -- a single root context per application, while each servlet in the application has its own child context)


So thus - if I was to use DispatchServlet (which I believe is Spring's main "handy-man") for doing servlet-controllers, each Servlet that I make in DispatchServlet will have its own IoC Container? And if all of this is running inside an application server like Tomcat along with back-end internal Java Spring code (which let us I assume has its own Spring IoC XML Contexts loaded through its own internal logic), will I ever be able to access those internal IoC containers through Servlets or Controllers?

Or is it impossible given the design of it all (so the IoC Context on the Controller-side would be restricted to each child Servlet-only while the internal IoC Containers running the main Java code would be restricted to its own internal context load of the Spring XML config)?
Mark Spritzler
ranger
Sheriff

Joined: Feb 05, 2001
Posts: 17249
    
    6

In a Spring MVC app you will create 2 ApplicationContexts. One for the web layer Spring MVC components, and one for the middle tier. The Web Layer beans will have complete access to the Middle Tier one, but not the other way around.

In Spring MVC in your web.xml you deploy a DispatcherServlet with a config file(s) for the web layer beans and you deploy a ContextLoaderListener with a config file(s) for the middle tier. This creates what we call a parent-child ApplicationContext relationship. The web layer beans are in the child application context and the middle tier in the parent. Child beans can see parent beans, but parent beans cannot see child beans.

Mark


Perfect World Programming, LLC - Two Laptop Bag - Tube Organizer
How to Ask Questions the Smart Way FAQ
Perry Terrance
Ranch Hand

Joined: Oct 02, 2009
Posts: 55
Mark Spritzler wrote:In a Spring MVC app you will create 2 ApplicationContexts. One for the web layer Spring MVC components, and one for the middle tier. The Web Layer beans will have complete access to the Middle Tier one, but not the other way around.

In Spring MVC in your web.xml you deploy a DispatcherServlet with a config file(s) for the web layer beans and you deploy a ContextLoaderListener with a config file(s) for the middle tier. This creates what we call a parent-child ApplicationContext relationship. The web layer beans are in the child application context and the middle tier in the parent. Child beans can see parent beans, but parent beans cannot see child beans.

Mark


This is interesting regarding this parent-child interaction. I am assuming though, that the MVC layer can see the Parent middle-layer Beans, but they cannot access those exact middle-layer Bean "instances" - per our Spring Singleton discussion correct? So while the MVC-layer can see the config file beans for the middle tier, it cannot access those exact instances if the middle-tier should so happen have ApplicationContext Spring Config calls in its internal code through its own internal Java logic and actually be modifying object fields in that specific IoC Container...

Whatever the MVC layer grabs will be always be in its own IoC Container instance, but with a Bean setup that includes the parent-level Bean configurations as well as its own Bean configuration?

I hope I am understanding this right....
Bill Gorder
Bartender

Joined: Mar 07, 2010
Posts: 1648
    
    7

Please have a read of :
http://static.springsource.org/spring/docs/3.1.1.RELEASE/spring-framework-reference/html/beans.html#context-introduction
and
http://static.springsource.org/spring/docs/3.1.1.RELEASE/spring-framework-reference/html/mvc.html#mvc-servlet

From the reference docs:

ApplicationContext instances in Spring can be scoped. In the web MVC framework, each DispatcherServlet has its own WebApplicationContext, which inherits all the beans already defined in the root WebApplicationContext. These inherited beans defined can be overridden in the servlet-specific scope, and new scope-specific beans can be defined local to a given servlet instance.


[How To Ask Questions][Read before you PM me]
Mark Spritzler
ranger
Sheriff

Joined: Feb 05, 2001
Posts: 17249
    
    6

Perry Terrance wrote:

This is interesting regarding this parent-child interaction. I am assuming though, that the MVC layer can see the Parent middle-layer Beans, but they cannot access those exact middle-layer Bean "instances" - per our Spring Singleton discussion correct? So while the MVC-layer can see the config file beans for the middle tier, it cannot access those exact instances if the middle-tier should so happen have ApplicationContext Spring Config calls in its internal code through its own internal Java logic and actually be modifying object fields in that specific IoC Container...

Whatever the MVC layer grabs will be always be in its own IoC Container instance, but with a Bean setup that includes the parent-level Bean configurations as well as its own Bean configuration?

I hope I am understanding this right....


Nope. The Spring MVC layer beans can access the Middle Tier Beans directly. I can inject a Bean from the middle tier application context into a bean in the mvc web layer application context.

So I have an OrderService and an OrderController. I can inject the one and only one instance of OrderService into the OrderController. Each instance is in a different ApplicationContext.

Mark
Perry Terrance
Ranch Hand

Joined: Oct 02, 2009
Posts: 55
Mark Spritzler wrote:
Perry Terrance wrote:

This is interesting regarding this parent-child interaction. I am assuming though, that the MVC layer can see the Parent middle-layer Beans, but they cannot access those exact middle-layer Bean "instances" - per our Spring Singleton discussion correct? So while the MVC-layer can see the config file beans for the middle tier, it cannot access those exact instances if the middle-tier should so happen have ApplicationContext Spring Config calls in its internal code through its own internal Java logic and actually be modifying object fields in that specific IoC Container...

Whatever the MVC layer grabs will be always be in its own IoC Container instance, but with a Bean setup that includes the parent-level Bean configurations as well as its own Bean configuration?

I hope I am understanding this right....


Nope. The Spring MVC layer beans can access the Middle Tier Beans directly. I can inject a Bean from the middle tier application context into a bean in the mvc web layer application context.

So I have an OrderService and an OrderController. I can inject the one and only one instance of OrderService into the OrderController. Each instance is in a different ApplicationContext.

Mark


Awesome! So it IS possible to have a single-persistent Spring Singleton Bean that spans both in the middle-layer and the Controller layer of the MVC in a JVM-running Application Server!!!

I wonder how this would work though?

In my first few posts in the thread, I was giving examples of how I was instantiating the IoC Containers manually via ApplicationContext calls to my "spring-config.xml." And from Sam's discussions, he verified to me that in each ApplicationContext call I make to "spring-config.xml" - I was making essentially a NEW IoC Container every time - even though I was calling the same-exact config file.

So now if we throw Spring MVC into the mix - how do I ensure that when my ApplicationContext loads in the back-end Java code with the one (and only one) Bean Instance of "spring-config.xml" - that then my MVC layer can grab that exact instance? I'm just trying to figure this out in a working example...
Mark Spritzler
ranger
Sheriff

Joined: Feb 05, 2001
Posts: 17249
    
    6

There is a distinction. In your first example you created two ApplicationContexts and passing it the same xml configuration. So the ApplicationContexts each would instantiate objects from that configuration.

In the Spring MVC example you had two TOTALLY DIFFERENT configuration files. One that declared the middle tier beans and one that declared the web layer beans. You pass the web layer beans xml to the DispatcherServlet, and you pass the middle tier xml to the ContextLoaderListener.

And in Spring MVC the DispatcherServlet that creates the web layer ApplicationContext looks up the middle tier applciation context from the ServletContext and calls the setParent() method.

Mark

Perry Terrance
Ranch Hand

Joined: Oct 02, 2009
Posts: 55
Mark Spritzler wrote:There is a distinction. In your first example you created two ApplicationContexts and passing it the same xml configuration. So the ApplicationContexts each would instantiate objects from that configuration.

In the Spring MVC example you had two TOTALLY DIFFERENT configuration files. One that declared the middle tier beans and one that declared the web layer beans. You pass the web layer beans xml to the DispatcherServlet, and you pass the middle tier xml to the ContextLoaderListener.

And in Spring MVC the DispatcherServlet that creates the web layer ApplicationContext looks up the middle tier applciation context from the ServletContext and calls the setParent() method.

Mark



Ok - so here is my confusion then:

My experience with regular Java Spring Context loads have always been through some sort of manual ApplicationContext call or manual BeanFactory call to do the initial bean load into the Java runtime and grab that specific IoC Container output-instance for the rest of the use of the program. So until my Java logic actually hits that Context load logic, my Spring Beans are not yet loaded into the JVM.

How will it work with the middle tier Beans and MVC - if I do or do not place my ApplicationContext or BeanFactory call in a specific portion of the code...

This may be a newbie question - but frankly - my Spring experience have always been through manual method load calls - so please enlighten me
Mark Spritzler
ranger
Sheriff

Joined: Feb 05, 2001
Posts: 17249
    
    6

Exactly. In a Spring MVC app, you do not have to create your own ApplicationContext in code, and with Annotations you will never have to call getBean in any of your code.

Using the web.xml file you enter in a <servlet-listener> with a Spring class called ContextLoaderListener, this listener gets called when your web app is being deployed by the Web container. When the single ServletContext gets created by the container, it then calls the listener class. Inside this listener class Spring has code that creates an ApplicationContext, loading in the xml file that you also declare in the web.xml as a <context-param> or via the file naming strategy of creating an xml file called "applicationContext.xml" and placing it in the WEB-INF directory.

Then in the web.xml you register the DispatcherServlet with a <servlet> tag and using an <init-param> point to your xml configuration file for your web tier components. Naming convention here is call your config file the name of your servlet as in <servlet-name> and "-servlet.xml" so if I have
<servlet><servlet-name>mark</servlet-name><servlet-class…….. ></servlet>

I create a file called mark-servlet.xml and put it in the WEB-INF directory.

So the DispatcherServlet has an init method that also creates an ApplicationContext for you. Loading in the mark-servlet.xml or whatever I call that file.

Hope that clears it all up.

If you want more information then you will need to read the Spring Framework documentation or get Craig Wall's excellent Spring IN Action 3rd Edition book.

Thanks

Mark
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Spring - Multiple IoC Containers with Singleton Bean in a JVM
 
Similar Threads
When are Beans in scopes other than singleton exactly loaded?
How to create NON SINGLETON beans in Spring ?
Help needed to set up Spring IOC in a web application
Cannot destroy singleton Spring bean and application context
A JSP consisting of a single jsp:useBean won't compilef