-
Notifications
You must be signed in to change notification settings - Fork 77
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Provide shortcut for CDI.current().select(xxx.class).get() #684
Comments
If you have hundreds of calls to If your application is "half CDI, half not", or something like that, I'd probably advise to build a single bridge instead of bridging ad hoc. Of course, I have no idea how your application really looks, so above are just a few random thoughts. And you can always do this: public class CdiUtil {
public static <T> T get(Class<T> clazz) {
return CDI.current().select(clazz).get();
}
} |
Ladislav is right that
This is also good point as by using |
Thank you both for your comments. I am accessing stateless service bean methods (running direct database queries) from entity beans. In the entity beans the following does not work:
I am aware of the workaround
I thought it might useful to all if the class CDI already provides such a shortcut such that it must not be implemented by "everybody". Maybe, you can help with this question: Is there another way to access service bean methods from entity beans? Thanks in advance. |
Hmm good question, the injection doesn't work because the lifecycle of those objects is not under control of CDI but rather JPA. In your case as a user, the dynamic resolution seems like the easiest way unless you'd want to create your own API through which you'd resolve JPA entities and which would attempt injection into those instances. That being said, I am not even sure it's possible, just thinking aloud :) One more note WRT to simplification of the dynamic resolution.
The reason why CDI always let's you go via
So I'm -1 on that simplification :) |
Okay, that makes sense, entity beans or JPA entities (I sure hope it's the latter :-) ) can't inject anything, because they have a completely different lifecycle, as @manovotn points out. My proposal would be to do something like this: @ApplicationScoped
public class ServiceBeanX {
public static ServiceBeanX get() {
return CDI.current().select(ServiceBeanX.class).get();
}
// ...
} The @Dependent
public class ServiceBeanX {
public static void with(Consumer<ServiceBeanX> action) {
var lookup = CDI.current.select(ServiceBeanX.class);
var instance = lookup.get();
try {
action.accept(instance);
} finally {
lookup.destroy(instance);
}
}
// ...
} And so on. This is how I would centralize lookup and possibly lifecycle handling of those services. The entities would use the Depending on how many of those service classes exist, what's their lifecycle and how they interact, you might also create a registry of those services and use that to obtain the instances. The only place where you would then use |
@manovotn I cannot really follow the second part of your argumentation. In cases there is no other way than to use
why not to make it easier by having the short-cut notation? This does not harm or change anything.
@manovotn I cannot really follow the second part of your argumentation. In cases there is no other way than to use
such as in the JPA entity beans where you cannot use @Inject, why not to make it easier by having the short-cut notation? This does not harm or change anything. |
@Ladicek many thanks for your extensive example. I am seeing what you are trying to achieve. What I dislike is the complexity that is introduced - and thus to be maintained - to gain a tiny performance advantage which is even not recognizable in the web application since the service beans are stateless anyway. They are just created on demand. The garbage collector does the cleaning job sooner or later anyway. Do I overlook something? I was not expecting that this tiny shortcut feature request is even worth to have a long discussion since it does not harm or change anything in the architecture. |
Let me show what I meant by examples. Imagine you have the shortcut and can do things like
Now, my first point was about making sure the bean is resolvable. Imagine you do this:
We didn't define
Now the second point - if you manually resolve
This is will just fine since the bean exists and you can use it.
NOTE: For simplicity sake I've skipped (in the code) bits that would help you determine if the bean is Many beans are often supplies by other dependencies and/or frameworks so assuming you always "know the whole universe" is not safe. Therefore, having the shortcut opens up way for multitudes of misusages and future issues. |
@manovotn I fully see the both points which makes sense from the global point of view. Of course, my expection was that My conclusion is slightly different: Whoever so far (mis)used the code fragment CDI.current().select(MyBean.class).get() without prior checking whether the instance is resolvable or not, will continue todo that. Actually, it is fine todo so and no misuse at all when all the usage relies on hardcoded classes. In case you use a non-defined class, your compiler will tell it. For such scenarios, the shortcut will make the code more concise and readable. The second argument that then you cannot do the cleanup is also valid but in case you don't care because you know that the garbage collector will do that job anyway after the invoking object is destroyed, everything is fine again. Many thanks for your detailed argumentation again. Cheers. |
The resulting set of beans can be tempered with by 3rd party libraries (or anyone else registering an extension for that matter). Or even by your own user registering a producer for a type + qualifiers that you already have.
Not sure I understand, the GC does not invoke your pre-destroy callbacks? Don't get me wrong, I understand your argument that in a closed world scenario, you can be sure it's safe to use the shortcut. |
Dear @manovotn i fully see all your points with all the potential issues and really appreciate your detailed explainations.
However, I am the optimistic guy. Therefore my standpoint is different: Why should I make the world more difficult than necessary for people who know what they do to prevent others from doing something that might lead to an issue for them, which in any case would easily be solvable. For instance, in our large application with the given requirements, it is safe to use everywhere "CDI.current().select(MyBean.class).get()". Hence, it would great to have such a shortcut to make the code more concise. So, I want to have a short notation for accessing beans from "everywhere"! As already said, it actually is not a big issue since one could go the way with the workaround:
But then everybody with these same requirements needs to do this additional work which the class CDI could easily take over once for all. Of course, this method does not free anybody who "needs checking whether the bean is resolvable" or "requiring predestroy actions" from their duty to do that over instance CDI.current().select(clazz) to fulfill their requirements. |
FTR In any case, I also don't think it's a good idea to use |
Would be great to have a shortcut for CDI.current().select(xxx.class).get().
My proposal would be: CDI.get(xxx.class).
I have several hundreds of such calls in my code. Such as shortcut would make the code more concise and thus better readable.
Thanks for consideration.
The text was updated successfully, but these errors were encountered: