My JSF Books/Videos My JSF Tutorials OmniFaces/JSF PPTs
JSF 2.3 Tutorial
JSF Caching Tutorial
JSF Navigation Tutorial
JSF Scopes Tutorial
JSF Page Author Beginner's Guide
OmniFaces 2.3 Tutorial Examples
OmniFaces 2.2 Tutorial Examples
JSF Events Tutorial
OmniFaces Callbacks Usages
JSF State Tutorial
JSF and Design Patterns
JSF 2.3 New Features (2.3-m04)
Introduction to OmniFaces
25+ Reasons to use OmniFaces in JSF
OmniFaces Validators
OmniFaces Converters
JSF Design Patterns
Mastering OmniFaces
Reusable and less-verbose JSF code

My JSF Resources ...

Java EE Guardian
Member of JCG Program
Member MVB DZone
Blog curated on ZEEF
OmniFaces is an utility library for JSF, including PrimeFaces, RichFaces, ICEfaces ...

[OmniFaces Utilities] - Find the right JSF OmniFaces 2 utilities methods/functions

Search on blog

Petition by Java EE Guardians

Twitter

vineri, 27 noiembrie 2015

JSF Scopes Tutorial - JSF None Scope

The none scoped beans lives to serve other beans
The none scoped beans lives to serve other beans. The none scope seems to be the "black sheep" of JSF scopes. Even its name doesn't inspire something useful. Practically, a managed bean in this scope lives as long as a single EL expression evaluation and is not visible in any JSF page - JSF will not store it, which means that the caller can use it only if it stores the evaluated reference itself. If the application scope lives the longest, this scope lives the shortest. But, if you inject the none scoped managed beans in other managed beans, then they will live as long as their hosts.  The none scoped objects used in the configuration file indicate managed beans that are used by other managed beans in the application. So, whenever you need a humble managed bean that is ready to be a part of a cool scope, such as a request or a session, you can annotate it with @NoneScoped, available in the javax.faces.bean package. Moreover, objects with the none scope can use other objects with the none scope.

Let's see a simple example:

@ManagedBean
@NoneScoped
public class InitBean implements Serializable {
   
 private static final Logger LOG = Logger.getLogger(InitBean.class.getName());
       
 private int init;

 public InitBean() {
  LOG.info("InitBean#Constructor invoked ...");
  init = 5;
 }

 public int getInit() {
  return init;
 }

 public void setInit(int init) {
  this.init = init;
 }
}

<h:body>              
 Current init value: #{initBean.init}  
 Current init value: #{initBean.init}  
 Current init value: #{initBean.init}  
</h:body>

Since we are using the init property in three ELs, the none scoped bean will be constructed three times (three different instances). But, this is happening in a single request! So, for each EL that uses a property from a none scoped bean, JSF will create a separate instance of that bean!


But, as we said above, the none scoped beans lives to serve other beans. Per example, let's inject the InitBean into a session bean, CountBean, as below:

@ManagedBean
@SessionScoped
public class CountBean implements Serializable {

 @ManagedProperty(value = "#{initBean}")
 private InitBean initBean;

 private static final Logger LOG = Logger.getLogger(CountBean.class.getName());

 private int count;

 public CountBean() {
  LOG.info("CountBean#Initializing counter ...");
  count = 0; // will be override in the init() method
 }

 @PostConstruct
 public void init() {
  LOG.info("CountBean#Initializing counter with @PostConstruct ...");
  count = initBean.getInit();
 }

 public void increaseCount() {
  count++;
  initBean.setInit(count);
  LOG.log(Level.INFO, "Current value: {0}", count);
 }

 public InitBean getInitBean() {
  return initBean;
 }

 public void setInitBean(InitBean initBean) {
  this.initBean = initBean;
 }

 public int getCount() {
  return count;
 }

 public void setCount(int count) {
  this.count = count;
 }
}
And, we adjust the JSF page as below:

<h:body>             
 Current init value: #{initBean.init}
 Current init value: #{initBean.init}
 Current init value: #{initBean.init}   
 <hr/>
 Current init value (via session bean): #{countBean.initBean.init}
 Current count value (via session bean): #{countBean.count}         
 <h:form>
  <h:commandButton value="Count" action="#{countBean.increaseCount()}"/>
 </h:form>      
</h:body>

Now, notice that the injected instance lives as long as its "host" lives - the session scoped bean, CountBean. You can notice this from the below two screenshots:



The complete application is available here.

Below you can see the diagrams for injecting JSF none scoped beans exemplified on a session scoped bean:


So, once you understand the none scope, it starts to look pretty useful. Compared to the rest of scopes this one is quite flexible. It allows us to "attach" a scope to scope-less data via injection. Practically, we can use @ManagedProperty in any bean of any scope for injecting scope-less data and expose them further as bean properties. Per example, in the same time, we can inject the a none scoped bean in a request, a session and an application scoped bean without the need to duplicate the bean and annotate them with acceptable scopes to be eligible for injection (remember that JSF doesn't allow us to use objects that have shorter lifespan than the objects you are calling it from).

See you in the next post about the CDI singleton pseudo-scope.

Niciun comentariu :

Trimiteți un comentariu

JSF BOOKS COLLECTION

Postări populare

OmniFaces/JSF Fans

Follow by Email

Visitors Starting 4 September 2015

Locations of Site Visitors