File APIs for Java Developers
Manipulate DOC, XLS, PPT, PDF and many others from your application.
http://aspose.com/file-tools
The moose likes JSF and the fly likes Newbie Singleton Enforcement Question Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


JavaRanch » Java Forums » Java » JSF
Bookmark "Newbie Singleton Enforcement Question" Watch "Newbie Singleton Enforcement Question" New topic
Author

Newbie Singleton Enforcement Question

Rob Shoults
Greenhorn

Joined: Nov 06, 2011
Posts: 14
I am a little confused about the enforcement of singleton status in a web app. I assume that adding a managed bean is the same as adding a singleton. However, the web app does not appear to enforce singleton status when implemented manually outside the attributes map.

For example,
Let's say I have 3 classes( bean1 (an application scoped managed bean), class 1(a singleton non-bean class), and bean2 (a request scoped managed bean)).
In bean1, I instantiate class 1 and store it as a property.
In bean2, when I call into the getInstance class method of class 1, I get a new object. So the run-time for the bean2 call does not seem to recognize that class 1 is already instantiated and attached to bean1.

I was expecting to get the same object reference instantiated in bean1 since class 1 is a singleton. If I use injection to to get access to bean1 from bean2, and then call the bean1's property, I get access to the first instantiation so I know class 1 is instantiated prior to the bean2 call.

Can someone help me understand why this works this way? Thanks in advance.
Tim Holloway
Saloon Keeper

Joined: Jun 25, 2001
Posts: 16101
    
  21

No, JSF does not concern itself with singletons. I can instantiate 5 "FooBeans" in a single app and store each under a separate name in a given scope or even use the same name AND class in different scopes. If you want a true Singleton, you have to tackle that yourself.


Customer surveys are for companies who didn't pay proper attention to begin with.
Rob Shoults
Greenhorn

Joined: Nov 06, 2011
Posts: 14
Tim,

That makes perfect sense and thank you for clarifying that. However, I still have the question of manual implementation. If I setup a class with a singleton design pattern, why does the framework not honor that?

For example,
Let's say I have 3 classes( bean1 (an application scoped managed bean), class 1(a singleton non-bean class), and bean2 (a request scoped managed bean)).
In bean1, I instantiate class 1 and store it as a property.
In bean2, when I call into the getInstance class method of class 1, I get a new object even though class 1 is already instantiated and stored as a property on bean1. Why is this?
Tim Holloway
Saloon Keeper

Joined: Jun 25, 2001
Posts: 16101
    
  21

To properly work with a singleton, you have to obtain it from a factory. A singleton factory will construct the bean on the first factory request, then return that same instance for each subsequent factory request.

However, JSF's construction faculties are limited to POJOs. When a bean is called for and not found, JSF invokes the bean class "newInstance()" method using a no-arguments constructor request. newInstance() does exactly what its name implies - constructs a new instance. There's no way to invoke a singleton factory.

There's also the little detail of request-scope objects themselves. Request scope is a very short-lived scope. Once a given HTTP request has been processed and responded to, the request-scope objects are all destroyed. New instances are created from scratch on the next request. And, of course, being new instances, they don't carry anything over from the now-nonexistent previous instances.

There are (at least) 2 ways to get singletons to participate in JSF's managed property functions.

The first way is rather ugly. It requires you to design and implement both the necessary factory facilities AND an EL Resolver that can be used to make the named object visible in EL code. That applies to both Managed Property expressions and EL on a View definition equally.

The second way is a lot easier, although it carries some freight. Just include the Spring Framework in the webapp. Spring Beans are singletons by default and all the fuss and bother is done automatically for you by the Spring bean factory. There's also a bridge class that you can configure into faces-config that will allow any named Spring Bean to be resolvable in EL.

I use Spring this way to manage all my persistent data services components (which are singletons), wiring them into the JSF managed beans as needed. It's quite convenient.
Rob Shoults
Greenhorn

Joined: Nov 06, 2011
Posts: 14
That is very helpful. Thank you. I will mark this as resolved.
 
It is sorta covered in the JavaRanch Style Guide.
 
subject: Newbie Singleton Enforcement Question