Avoid auto-instantiation of managed bean when injected as #ManagedProperty - jsf

I have a requestscoped bean which can receive its data from three different viewscoped beans (from 3 different pages). The beans are JSF Managed Beans.
When I use ManagedProperty in the request scoped for 3 different view scoped beans, it instantiates the view scoped beans which is what I do NOT want. I want to simply know from which bean it is being called from and then call a specific method (different) for each bean.
How can I check which bean is instantiated and in scope so I can call the correct bean's method?

Looks like it's pretty simple. I was reading one of Balus's posts. I simply used ManagedProperty(value="#{viewScope.managedBeanName}") . It did not instantiate. For the inscope, it gave me the created bean :). Happy

Related

Split CDI bean in windowscope for separation of concerns

I have a JSF application with RichFaces 4.5.8, deltaspike for CDI beans, and EJBs which runs in an EAP 6.3. I have a page with two tables and several popupPanels. The page is backed by a CDI bean controller in WindowScope. By now the page becomes larger and larger, because the popupPanels have a lot of controls and actions.
The xhtml page is separated by composite components and ui:include's which works fine, but the CDI bean becomes larger an larger. I would like to move the action methods of the popupPanels into other CDI beans, but for me it sounds strange to have several windowScoped CDI beans in one page.
What would you do to split up the large CDI bean?
Best regards
#DarWhi's comment is correct - you may use as many WindosScoped beans in your page as you want, all of them will live only with one window. There is no restriction that you must use only single bean in the JSF page. You just need to give a name using #Named to all of such beans.
If you prefer to have only one WindowScoped bean per window, you may still separate your logic into multiple beans,. Just inject all child beans into the WindowScoped bean, and then reference actions in child beans using dot notation: #{viewScopedBean.childBean.action.
You may use variables to store references to childBeans and make your code in JSF shorter, see this answer.

How to instantiate a backing bean on page load

For a project we are migrating some java applications to WebSphere 8.5. In the process we are trying to get rid of some legacy frameworks. One of them is shale (apache attic). The only component from shale that is used is the view controller to instantiate a request scoped jsf managed beans for every page. Every bean has an init method that is called on page load. I'd like to use #PostConstruct on this method. The only problem I have that the bean gets instantiated when a method on the bean is called. Unfortunately the bean is not always called and the init method does populate data on a session scoped bean. There is a naming convention that links pages and beans so we could use a listener to instantiate the bean based on the request. Another solution might be changing the scope to viewscope (probably to much a hassle on websphere 8.5).
I was wondering if there is something I can do to make the PostConstruct work? And are there other options I'm missing?
edit:
I have a PhaseListener in place that performs the basic functionality. It matches the requested page to the corresponding bean (by naming convention). The following is used to instantiate the bean but it looks a bit ugly.
expressionFactory.createValueExpression(elContext, "#{" + managedBeanName + "}", Object.class)
Is there a more elegant way to do this?
Perhaps you could try using <f:event/> ?
In your view, you could add this to the page.
<f:event type="postAddToView" listener="#{backingBean.myInitMethod()"/>
https://stackoverflow.com/a/14004230/4706826
Gives you info on when the events get executed.
Put a #PostConstruct annotated method in the backing bean. This annotation tells the bean to execute the annotated method every time its constructor is being called.
Example:
#ManagedBean
#ViewScoped
public class MyManagedBean{
#PostConstruct
public void initView() throws Exception{
...initialize page values, execute database queries, etc.
}

JSF Managed bean and managed property both necessary?

I'm new to JSF and was wondering:
If I have a controller that handles all the work for a given page and a bean that holds all the data for said page, is It necessary to have both the
#ManagedProperty(value="#{myBean}")
annotation on the controller and the
#ManagedBean(name="myBean")
#SessionScoped
annotations on the form bean?
Managed beans in JSF are used to store the state of a web page. The JSF implementation is responsible for creating and discarding the bean objects( hence the name managed bean).
For every class you write #ManagedBean, the bean object is created by the JSF implementation as and when it detects an usage of the bean with the name(you can either sepcify a bean name or leave it to JSF to use the default name-class name with the first character changed to lowercase). The object created is placed in a map of the specified scope. Each scope has a map that it uses to store bean objects which have that scope specified.
Now if you need the values of these beans in your controller, you have to inject it using the ManagedProperty annotation. Note that you would need to provide the controller with a setter method for the managedProperty.
So to answer your question, the managedBean annotation is required to tell the JSF implementation to manage the bean instance and store the values in the table specific to the session scope. And the ManagedProperty annotation is needed to use that bean stored in the current session so that you can access all of its values.
We use #ManagedBean annotation to register a java bean with a JSF framework. This is a replacement for a faces-config.xml <managed-bean> element. We typically do not use name attribute because it already defaults to a simple class name camel cased.
We use #RequestScope and other scope annotations to explicitly specify the scope we want via annotation. This is equivalent to specifying<managed-bean-scope> xml entry. If you don't specify the scope it will be defaulted to #NoneScoped.
We use #ManagedProperty and specify an EL-expression in its value attribute to use JSF-provided dependency injection engine for JSF artifacts like other managed beans with broader scopes and EL-defined variables like param. We do it in case we need the injected values in other JSF artifacts, most typically beans. The injected values are available in bean's #PostConstruct-annotated method. This is an alternative to <managed-property> xml entry.
To sum it up. Use #ManagedBean #RequestScoped to register a bean with JSF framework. Use #ManagedProperty inside this bean to be able to reference among others other JSF beans with the same or broader scopes in this bean. In case you don't need to reference other beans in the created bean you don't need to use the #ManagedProperty annotation as it's purely optional.

WebBeans context with scope type annotation #SessionScoped does not exist within current thread

I have a bean that does some logic, I call it logicBean,
and it has a sessionscoped bean as field with #Inject.
I use this logicbean in two situations in one JAVA EE6 Application,
1. in servlet.
2. in message driven bean.
In the second situcation, I got a excetion
"WebBeans context with scope type annotation #SessionScoped does not exist within current thread".
I know there is no sessionScope in MDB, so I made another bean, and want to
inject it to logicBean dynamicly to alternative the sessionScoped bean.
I do not know how to do this.
please help me, thanks.

get a backing bean property value from another bean

It is possible to access or to get a backing bean property value from another backing bean in JSF?
Yes, it is possible.
You can access another beans in the context by Application#evaluateExpressionGet(). You can also inject a bean as managed property of other bean in faces-config.xml. If you're already on JSF2, you can even use #ManagedProperty annotation like follows:
#ManagedProperty(value="#{bean}")
private Bean bean;

Resources