JSF beans instantion: Are only the beans referenced in the view instantiated? - java

I'm guessing that if I have 6 requestscoped beans, only those referenced by the current view ( for instance by using #{foo.bar}) are instantiated. Is that assumption correct? In that case the only bean created would be foo, and not foo2, foo3, etc that are also requestscoped or viewscoped, etc.
Does this happen to both CDI's #Named and jSF's #ManagedBean beans?

Yes, it is correct.
You can test that by logging a message / adding a breakpoint in the constructor of all beans.

Related

How can I reach JSF #Singleton Bean from inside #SessionScoped Bean and vice versa?

My purpose is to have a #Singleton class which runs automated scheduled methods throughout the application on a cloud server. But I also have #SessionScoped beans which I would like to communicate with.
Is it possible to reach a #SessionScoped bean if I'm not in a user's web-session and the reverse: How can I use my #Singleton Bean as a user from my session?
Thanks and best regards!
You can reach Singleton Bean in SessionScoped Bean using application context to get Singleton bean or maybe injection in SessionScoped Bean.
context.getBean(SomeSingletonClass.class)
To do the reverse, there is no good way, you can put sessions in list of WeakReference inside se Singleton bean.

Why scope in Spring affects loading of class in Spring

Class Student Depends on class Result
<bean id = "result" lazy-init = "false">
</bean>
<bean id = "student" lazy-init = "true">
</bean>
Result: result bean will be loaded at container start-up and student will be loaded when we call getBean method.
<bean id = "result" lazy-init = "false" scope = "prototype">
</bean>
<bean id = "student" lazy-init = "true" scope = "Singleton">
</bean>
Result: No bean will be loaded at container start-up.
Question: Why scope is affecting class load; what does scope have to do with class load time?
According to documentation
The non-singleton, prototype scope of bean deployment results in the
creation of a new bean instance every time a request for that specific
bean is made. That is, the bean is injected into another bean or you
request it through a getBean() method call on the container. As a
rule, use the prototype scope for all stateful beans and the singleton
scope for stateless beans.
Since you didn't yet call getBean or inject it to another bean, this bean is not been created.
By the way, even when you declared your singletone bean as lazy-init="true", it will be created, if you'll inject it (for example with #Autowired annotation) to other non-lazy bean.
A bean of scope singleton is a bean that is created once per application context. A bean of scope prototype is a bean that is instantiated every time.
In other words if your have two classes that autowire a singleton scoped bean, all instances of those two classes will reference the same single instance of the bean. Doing the same with autowiring a prototype scoped bean will create a new instance for each instance that is autowired.
The property for lazy-init defines when the bean is instantiated: As a prototype scoped bean is instantiated each time there is no difference if the property is set to true or false, because the bean is instanciated when it is used (either by being autowired or by programmatic retrieval from the context). For a singleton scoped bean however it does make a difference:
If lazy-init is set to false (which is the default), the bean is instantiated on startup.
If the property is set to true, the bean is instantiated on the first use (through autowiring or programmatic retrieval from the context).
Defining a lazy load singleton bean may come in handy in cases where the bean may be costly to create and may only be used in special cases, the the application may actually run without ever calling any method on that bean.
Take a look at the Spring IoC container documentation, which goes into great detail.
I would like to put the theory in a simple manner which will help you understand better,
Only Singleton beans are eager loaded | prototype beans are lazily loaded(every req or indirect references)
If singleton bean is defined as lazy-init=true (by-default its false) then bean will be instantiated on first usage(using getBean or any indirect reference)
But for prototype bean lazy-init does not make any diff if making lazy-init=true or false as it will be lazily loaded always
You can try using #PostConstruct to play around different combinations in spring bean injections to know when beans are getting instantiated.

JSF a field of managedBean in sessionScope

We can put whole bean in sessionScope.
<managed-bean>
<managed-bean-name>managedBeanList</managed-bean-name>
<managed-bean-class>com.org.SomeMBean</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
But is there anything like we can put only a field of that managed bean in sessionScope?
like...
public class SomeMBean{
public String mySessionScopeVariable; // Is there any way only this field will be in sessionscope continusly and not whole bean.
//getter setter of that variable.
}
No this is not possible.
You should separate the field in a separate session scoped bean and use #ManagedProperty to inject it into your narrower scoped bean.
I don't see how. I'm no expert on JSF but to access an attribute in the ManagedBean or any bean for that matter one would need the bean since the attribute cannot exist without the bean. If you are thinking that your managed bean is bloating the session size set the heavy variables to null to save the memory. But apart from that i don't see any other way.

Backing Beans - which of them should be scoped?

I have two kinds of backing beans in my JSF application:
Managed Beans (#ManagedBean(name="bean"))
Entity Beans (#Entity)
Which of them should be scoped (request/session/view/application/no)?
I'm having all of my managed beans scoped and entity beans not now (I had also entity beans scoped in the past and it seems to be the same as without scope). And in addition "not" could mean, that entity beans are request scoped.
Thanks for the explanation :)
The entity beans doesn't need to have a JSF managed bean scope assigned. They are supposed to be assigned as a property of a JSF managed bean. So basically, they will get the same scope as the JSF managed bean where it is been declared as a property. The JSF managed bean scope annotations works only in a #ManagedBean class. The entity beans are also not necessarily to be categorized as "backing beans". They are more "value objects".
You can see it as a further division of the "V" of the complete JSF MVC picture in another mini-MVC: the JSF managed bean is the controller, the Entity is the model and the XHTML file is the view.
See also:
What components are MVC in JSF MVC framework?
I would say your Managed Beans should be scoped .
and not the entity beans,
Thats assuming that entity beans are pojhos and all the operations are in
managed Bean.
I am answering this wrt JSF v 1.1
Hope this helps.

How to do something on session start in Spring MVC?

I need to initialize every new http session with some values. How do I do that?
I tried to create a session-scoped component and initializing session in #PostConstruct, but session-scoped beans are not eagerly created until I request access them.
If you are absolutely certain that your want eager initialization, you can do the following:
define an interceptor for all beans
defina a <lookup-method> for that interceptor:
<lookup-method name="getCurrentSessionBean"
bean="yourSessionBeanToInitialize"/>
define the interceptor abstract, with an abstract method getCurrentSessionBean()
create a flag initialized on the bean
on each interception, call the lookup method and it will return an instance of the bean from the current session. If it is not initialized (the flag), initialize it
you can also use #PostConstruct and spare the initizlied flag
Another option is to:
define a HttpSessionListener in web.xml (or with annotations if using servlet 3.0)
use WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext) to obtain the context
call getBean(..) to get an instance of the session-scoped bean
it will be initialized with #PostConstruct at that point
The first option is "more spring", the second is easier and faster to implement.

Categories

Resources