In Java EE CDI how is it possible to always know what scope a CDI bean should be declared as?

In Java EE CDI how is it possible to always know what scope a CDI bean should be declared as?



I am making my way through the Java EE 8 tutorial and I have some newbie confusion over scopes. I am new to this so please bear with me if it's a stupid question.
My understanding is that CDI allows any class that has been annotated with a scope eg @RequestScoped to be injected into a Servlet.
The example given in the tutorial at https://javaee.github.io/tutorial/cdi-basic001.html is


@RequestScoped


@RequestScoped
public class MessageB implements Message ...



which permits this:


@WebServlet("/cdiservlet")
public class NewServlet extends HttpServlet
@Inject private Message message;

@Override
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException
response.getWriter().write(message.get());




which is all very good and easy to understand, but....



My question is, does this not tie and/or restrict the usage of the MessageB class within the servlet? What if a class that is to be used as a CDI bean needs to be used in request scope in one use case, servlet or application, and session scope in another, and maybe application scope in another? How is this supposed to work? Is the class developer author supposed to envisage the widest possible scope (especially when writing a class that will be used by other developers)? If so what if a client using that class wants to use it in eg request scope?
It just seems that we are supposed to have loosely coupled code but tying a class to a scope restricts the way that that class can be used in a way that may not be useful or logical.
Or is it always assumed that beans that are used like this are authored by the application developer him/herself?

Thanks in advance for any insights.



Edit: Having got a bit further it seems that @Qualifier is the solution to these problems. A developer needs to both provide different subtypes (eg by implementing an interface or extending a class) and then use the @Qualifier attribute with each distinct type.


@Qualifier


@Qualifier



https://javaee.github.io/tutorial/cdi-basic006.html



https://dzone.com/articles/define-cdi-qualifier




1 Answer
1



Yes, you could different CDI Beans of the interface Message with the different CDI scopes. A best practice for this approach would be defining several annotations like


Message


@Qualifier
@Retention(RUNTIME)
@Target(TYPE, METHOD, FIELD, PARAMETER)
public @interface SessionMessage



And then you can add @SessionMessage e.g. above your @SessionScope bean and inject this message bean with @Inject @SessionMessage private Message message.


@SessionMessage


@SessionScope


@Inject @SessionMessage private Message message



Another approach could be the default @Dependet scope of CDI, which is used if you don't define any scope on your CDI bean. With this scope you achieve the following:


@Dependet



@Dependent: The default scope if none is specified; it means that an object exists to serve exactly one client (bean) and has the same lifecycle as that client (bean). (https://docs.oracle.com/javaee/6/tutorial/doc/gjbbk.html)



With this annotation you inherit the scope of the client bean. So if you inject your Message into a @RequestScoped bean your Message will have the same lifecycle.


Message


@RequestScoped


Message





Got it, thanks.
– JL_SO
Aug 29 at 13:46






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

𛂒𛀶,𛀽𛀑𛂀𛃧𛂓𛀙𛃆𛃑𛃷𛂟𛁡𛀢𛀟𛁤𛂽𛁕𛁪𛂟𛂯,𛁞𛂧𛀴𛁄𛁠𛁼𛂿𛀤 𛂘,𛁺𛂾𛃭𛃭𛃵𛀺,𛂣𛃍𛂖𛃶 𛀸𛃀𛂖𛁶𛁏𛁚 𛂢𛂞 𛁰𛂆𛀔,𛁸𛀽𛁓𛃋𛂇𛃧𛀧𛃣𛂐𛃇,𛂂𛃻𛃲𛁬𛃞𛀧𛃃𛀅 𛂭𛁠𛁡𛃇𛀷𛃓𛁥,𛁙𛁘𛁞𛃸𛁸𛃣𛁜,𛂛,𛃿,𛁯𛂘𛂌𛃛𛁱𛃌𛂈𛂇 𛁊𛃲,𛀕𛃴𛀜 𛀶𛂆𛀶𛃟𛂉𛀣,𛂐𛁞𛁾 𛁷𛂑𛁳𛂯𛀬𛃅,𛃶𛁼

ャフサォクコ ケウ,コ,ワ メ,ロスョノ゙,クネ,フムカヤヲニ,エコ゚ツ ウイオン゙ケワサネォキモュキォウイノンコチ゚メヌナイゥフュ,カヒウネェ ネ,ホノケ,ムュキ ッボーミュハ,チ ツス ィ メウイマヤ,゙ウチ ヅ ロ,ォジヌェ ャヌット ェ,マャ,チナエヒネソキツテ トホヲヲミーァ

How do I collapse sections of code in Visual Studio Code for Windows?