Backing Beans - which of them should be scoped? - java

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.

Related

List the request- and session-scoped beans that are created by SpringMVC

If there's a list of these already available on the web, please link it. I couldn't find any such thing using the Googles.
Request-scoped beans:
javax.servlet.http.HttpServletRequest
Session-scoped beans:
javax.servlet.http.HttpSession
Well it really depends on what you've told Spring to create, but you'd see this in a default setup.
REQUEST:
for(String key : Collections.list(request.getAttributeNames())) {
System.out.println( key );
}
RESULT:
org.springframework.web.context.request.async.WebAsyncManager.WEB_ASYNC_MANAGER
org.springframework.web.servlet.DispatcherServlet.CONTEXT
org.springframework.web.servlet.DispatcherServlet.LOCALE_RESOLVER
org.springframework.web.servlet.HandlerMapping.bestMatchingPattern
org.springframework.web.servlet.DispatcherServlet.OUTPUT_FLASH_MAP
org.springframework.web.servlet.DispatcherServlet.FLASH_MAP_MANAGER
org.springframework.core.convert.ConversionService
org.springframework.web.servlet.DispatcherServlet.THEME_SOURCE
org.springframework.web.servlet.HandlerMapping.pathWithinHandlerMapping
org.springframework.web.servlet.HandlerMapping.uriTemplateVariables
org.springframework.web.servlet.DispatcherServlet.THEME_RESOLVER
SESSION:
for(String key : Collections.list(session.getAttributeNames())) {
System.out.println( key );
}
RESULT:
(empty)
Autowiring happens once, after the object creation, and this is a main thing to keep in mind when reasoning about autowiring and different scopes.
About your question, there's in fact no issue when it comes to injecting longer living beans inside a short-lived beans. Its only important that you're aware of it and that it fits your semantic.
Other way around is a bit trickier. So injecting shorter lived beans, inside a longer lived beans. The proper way for doing this is leaning on proxies. If you're injecting a request-scoped bean inside a session-scoped bean, and if the request-scoped bean is proxied, than the proxy will be created only once, but will create a request bean on each request.
Its a simplification of what is described in the docs and available at http://docs.spring.io/spring/docs/current/spring-framework-reference/html/beans.html#beans-factory-scopes-other-injection
You can autowire anything that Spring can build. Whether or not you should is another matter.
For example, it is utterly senseless to autowire a bean with Step scope (from batch processing) to a request scoped bean.

Are model beans singleton in spring?

In spring the classes annotated with #Controller, #Service, #Repository, #Component act as Spring beans and will be instantiated by Spring container in singleton (Default scope).
Here the model beans are not annotated with any stereo type annotations.
My question here is whether the model beans are singleton or not i.e., if they come under Spring container.
If it is true then, how has the concurrency issue been handled?
Model attributes, ex. from #ModelAttribute annotated parameters, are not beans. They are not managed by the BeanFactory / ApplicationContext. They are created by the DispatcherServlet's MVC stack and provided to you. There's no concurrency issue (unless you create one) because a Servlet container handles each request in a single thread.

Which type of beans are injectible?

With the concept of CDI in EJB3.X, you can inject the beans or entities.
What i want to know is: which types of beans you can inject.
Session Bean in Entity? Entity in MDB, etc???
How can I find a table that show the possiblities what i can do/inject in CDI concept.
Take a look at DZone Ref Card can be found here.
Quick Look:
Session Beans can be injected into Session Beans, MDBs can be injected in SessionBean, Entities can be injected in SessionBean.
Stateful beans shouldn't be injected in stateless beans.

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

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.

Deserialized bean needs scoped dependencies

How can I inject dependencies into a deserialized bean?
Some of my Spring beans should be serialized during the render-response phase of our JSF application, and then deserialized at the beginning of the next request. Some of those beans have dependencies which are scoped to the request. If I configure the dependencies with the scoped proxy ("<aop:scoped-proxy>"), I can't serialize my dependent beans - the proxy isn't serializable.
So right now we do it by declaring the appropriate member variables of the serialized bean classes as transient, and then calling context.getAutowireCapableBeanFactory().configureBean(bean, name) just after deserializing the beans - but this sucks, because the bean's initializer is called again. (As for other dependencies that are in the same scope, are not transient, and are deserialized, I'm not even sure why they don't get overwritten by configureBean, but I don't think they are.)
What's better? Should I just get the bean definition, loop through it, find the dependencies that are scoped to the request, and then call getBean(name) on the context?
(BTW, I'm not sure it makes a difference, but we are using Spring kind of weirdly. We instantiate a new ClassPathXmlApplicationContext for each non-posted-back HTTP request, rather than a single WebApplicationContext. Upon postback, we deserialize the beans. So when I say "scoped to the request", I'm lying; these beans are actually singleton-scoped. I'd like to use the WebApplicationContext and the more sane scoping with it, but as far as I can tell, that's orthogonal to our problem at the moment.)
It makes all the difference - I've been using spring with JSF for quite a long time and hadn't had any serialization problems. The way to go is simply define the following in your faces-config.xml:
<el-resolver>
org.springframework.web.jsf.el.SpringBeanFacesELResolver
</el-resolver>
This integrates spring with JSF by providing spring beans (using the request and session spring scopes) to JSF pages.
So, I'd advice for changing your approach drastically so that you aren't bug with such problems in the future.

Categories

Resources