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.
Related
I have been trying to understand spring beans. As per my understanding, by default all beans are singleton and a singleton bean with lazy-init property set to true is created when it is first requested and singleton bean with lazy-init property set to false is created when the application context is created.
So, in an application, when a user request comes in ( where each request is a separate thread), do all these threads share the same singleton beans when requested within the program/class?
Yes, if the bean is created with default scope, the bean is shared across threads. However, another scope can be used to achieve the behaviour you mentioned.
See: https://docs.spring.io/spring-framework/docs/3.0.0.M3/reference/html/ch04s04.html?
Yes, by default (scope == 'singleton'), all threads will share the same singleton bean. There are two other bean scopes, session and request, that may be what you're looking for. The request scope creates a bean instance for a single HTTP request while session scope maintains a unique bean for each HTTP Session.
For a list and description of all of the Spring bean scopes, check out: Spring bean scopes
The best way to understand this is to understand how #Autowired annotation works.
Or in other words to understand "Spring Dependency Injection".
You said, "
by default all beans are singleton
We use #Autowired when injecting one layer into another between two layers.
If exemplify: Suppose, I want to inject UserService UserController. UserService is a Singleton bean. Creates an instance from UserService and Stores its cache. When we want to inject this service with #Autowired annotation. This annotation brings the UserService stored in the cache.
In this way, Even if we do this inject operation in many classes.#Autowired inject an instance of UserService with singleton bean instead of dealing with one UserService at each time. It saves us a big burden.
This is the fundamental working logic of Spring Singleton Bean.
Also, Spring Ioc Container manages this whole process.
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.
I have below bean defined in application context xml file:
<bean id="logRoutingTable" class="com.symantec.cas.ucf.plugin.router.RoutingTable">
</bean>
And using it in java file with #Autowired
#Autowired
private RoutingTable routingTable;
The above code is working properly. But now I realized that instance name routingTable is different than bean id logRoutingTable. So is it not necessary to match both bean id and instance member?
No. It is not required. The instance variable can have any name. Spring framework automatically searches for matching bean. In case you have more than one bean for same class then you have to use
#Qualifier("beanName")
for matching by bean Name.
As long as there is only one bean matching (IS-A) RoutingTable, Spring will allow the injection.
If you had another bean matching, there would be a conflict that you could solve with #Qualifier(See mykong example) or by renaming the instance variable to match the bean id.
I have defined a spring bean extending another bean defined as singleton. Which means this:
<bean id="aChildBean" parent="aParentBean">
<!-- ......->
</bean>
Now, I wonder if I could define the scope "request" in this bean. I know that the child bean inherits the scope of the parent, but I'm not sure that this could logically work. When I tested this, Spring spring generated the exception below:
Error creating bean with name 'aChildBean': Scope 'request' is not active for the
current thread; consider defining a scoped proxy for this bean if you intend to refer
to it from a singleton; nested exception is java.lang.IllegalStateException: No thread
bound request found: Are you referring to request attributes outside of an actual web
request, or processing a request outside of the originally receiving thread? ...
So, I wonder if I could do such action. And, if the definition of a scoped bean solve the problem ?
Thanks in advance for your answers..
Quote from documentation:
A child bean definition inherits constructor argument values, property values, and method overrides from the parent, with the option to add new values. Any initialization method, destroy method, and/or static factory method settings that you specify will override the corresponding parent settings.
The remaining settings are always taken from the child definition: depends on, autowire mode, dependency check, singleton, scope, lazy init.
So, your bean IS "request" scoped, but a "request" scope only makes sense in a web environment. See here the documentation of "request" scope.
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.