2

In my jsf application I have plenty of static FacesContext related utility methods. And always I ask myself the same question?

Should I pass the context via an argument to the method? Or use FacesContext.getCurrentInstance()

For example:

public static <T> T getInstance(final Class<T> type, final FacesContext context, final String elExpression)
{
    return context.getApplication().evaluateExpressionGet(context, elExpression, type);
}

Even more confusion appears, since the validator and converter interfaces use the context as an argument.

Can there be more then one FacesContext?

ElderMael
  • 7,000
  • 5
  • 34
  • 53
djmj
  • 5,579
  • 5
  • 54
  • 92

2 Answers2

4

Calling FacesContext.getCurrentInstance() vs passing it has performance and functionality implications.

As you might have noticed, the majority of the JSF API itself uses passing. This is done because passing is much faster than accessing a thread local variable. On top of that, with passing, a method down the call chain can wrap a FacesContext more easily and in a controlled way.

So typically FacesContext.getCurrentInstance() is used for bootstrapping, and you'd use passing afterwards.

If it concerns only a few calls, and the verbosity gets to you, by all means use FacesContext.getCurrentInstance() as well. Just be aware if it concerns many calls, there might be some (small) performance repercussions.

Arjan Tijms
  • 37,782
  • 12
  • 108
  • 140
2

In a previous question, BalusC anwered this:

The FacesServlet is namely the one who creates the FacesContext and puts it as a ThreadLocal in the current HTTP request.

If your utilities are going to be used in a thread other than the one serving the HTTP request, then you must pass the FacesContext to avoid nulls. Other than that, I think it helps you to avoid verbosity calling FacesContext.getCurrentInstance() in every method.

Or you could use a combination of both, one without :

public static <T> T getInstance(final Class<T> type, final String elExpression){
    return JsfUtils.getInstance(type, FacesContext.getCurrentInstance(), elExpression);
}


public static <T> T getInstance(final Class<T> type, final FacesContext context, final String elExpression){
    return context.getApplication().evaluateExpressionGet(context, elExpression, type);
}

This will help you with performance tradeoffs (about accessing the threadlocal) and will help you with verbosity if you want to, but you will need to remember about thread safety with your context.

Community
  • 1
  • 1
ElderMael
  • 7,000
  • 5
  • 34
  • 53