Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Utility methods in application scoped bean

Do you think it is a good idea to put all widely used utility methods in an application scoped bean?

In the current implementation of the application I'm working on, all utility methods (manipulating with Strings, cookies, checking url, checking current page where the user is etc.) are all put in one big request scoped bean and they are referenced from every xhtml page.

I couldn't find any information on stackoverflow if the approach of putting utility methods in an application scoped bean would be a good or a bad choice.

Why I came across this idea is the need of reusing those methods in a bean of a wider scope then a request scoped bean (like view or session scoped bean). Correct me if I'm wrong but you should always inject same or wider scoped beans i.e. you shouldn't inject request scoped bean inside a view scoped one.

I think using utility methods from application scoped bean should be beneficial (there won't be any new object creations, one object will be created and re-used across all application), but still I would like a confirmation or someone to tell me if that is a wrong approach and why is it wrong.

like image 451
ontime Avatar asked Apr 19 '16 12:04

ontime


People also ask

What does the @ApplicationScoped annotation indicate?

Annotation Type ApplicationScoped. Specifies that a bean is application scoped.

What does@ ApplicationScoped mean?

The Soup class is an injectable POJO, defined as @ApplicationScoped . This means that an instance will be created only once for the duration of the whole application.

How do you decide what should be the scope of the bean?

You normally want to use this scope only on beans which should live as long as the bean where it's being injected. So if a @NoneScoped or @Dependent is injected in a @SessionScoped , then it will live as long as the @SessionScoped bean.

Which scopes defined in the Java EE specifications are related to Java Server Faces JSF )?

The first three scopes are defined by both JSR 299 and the JavaServer Faces API. The last two are defined by JSR 299. All predefined scopes except @Dependent are contextual scopes. CDI places beans of contextual scope in the context whose lifecycle is defined by the Java EE specifications.


Video Answer


1 Answers

As to the bean scope, if the bean doesn't have any state (i.e. the class doesn't have any mutable instance variables), then it can safely be application scoped. See also How to choose the right bean scope? This all is regardless of the purpose of the bean (utility or not). Given that utility functions are per definition stateless, then you should definitely be using an application scoped bean. It saves the cost of instantiating on every single request.

As to having utility methods in a managed bean, in object oriented perspective this is a poor practice, because in order to access them from EL those methods cannot be static while they should be. You can't use them as real utility methods in other normal Java classes. Static code analyzers like Sonar will mark them all with a big red flag. This is thus an anti-pattern. The correct approach would be to keep using a true utility class (public final class with private Constructor() with solely static methods) and register all those static methods as EL functions in your.taglib.xml as described in How to create a custom EL function to invoke a static method?

At least, this is what you should be doing when you intend to have a publicly reusable library such as JSTL fn:xxx(), PrimeFaces p:xxx() or OmniFaces of:xxx(). If you happen to use OmniFaces, then you could, instead of creating a your.taglib.xml file, reference the class in <o:importFunctions>. It will automatically export all public static methods of the given type into EL function scope.

<o:importFunctions type="com.example.Utils" var="u" />
...
<x:foo attr="#{u:foo(bean.property)}" />

If you don't use OmniFaces, and this all is for internal usage, then I can imagine that it becomes tiresome to redo all that your.taglib.xml registration boilerplate for every tiny utility function which suddenly pops up. I can rationalize and forgive abusing an application scoped bean for such "internal usage only" cases. Only when you start to externalize/modularize/publicize it, then you should really register them as EL functions and not expose poor practices into public.

like image 185
BalusC Avatar answered Oct 19 '22 17:10

BalusC