add support for synthetic bean injection points#833
add support for synthetic bean injection points#833Ladicek wants to merge 3 commits intojakartaee:mainfrom
Conversation
|
This is a draft, because it's very much not ready. The biggest open question is: does One way would be to say something like:
That is obviously a breaking change, but I don't see a better way that wouldn't be more breaking. |
👍 Although a breaking change it makes perfect sense IMO. |
|
What are you trying to fix by adding this? I don't see an explanation of the problem or a linked issue. |
In a build-time environment, such as Quarkus, injection point metadata has to be recorded for any |
|
What @mkouba says is just the reason why I'm submitting this PR now. The ultimate cause is feature parity -- Portable Extensions allow this, while Build Compatible Extensions do not. |
03541db to
039589f
Compare
I eventually decided that this is something we should keep doing in Quarkus, outside of the specification. The spec should stay silent on this. |
|
Thanks @Ladicek for the explanation on the call. As I understand it now: With portable extensions, you can create a synthetic bean by implementing Other extensions can also modify the injection points by observing As far as I can see, there's no way to link an injection point to an injected dependent bean to allow the dependent bean to inspect where it's been injected. This PR would add equivalent functionality to build compatible extensions. Injection points can be added to the synthetic bean and will be validated by the container and available for other extensions to inspect with Additionally, Quarkus want the ability to do some additional out-of-spec optimisations (such as removing any beans which aren't needed), and having this functionality in build compatible extensions would add a way for the user to indicate that certain beans are used by their synthetic bean and can't be optimised away. |
|
Actually, let me push this PR back to draft, because there's a bit of a conflict we need to resolve: the Portable Extensions API allows this, but expect a direct implementation of |
039589f to
591d477
Compare
|
I found some time and updated the proposal with a somewhat better (I believe) API. The main question remains (and it's why I'm keeping this PR as a draft): how can we bridge this with Portable Extensions, which expect full blown |
da88af4 to
bc1874b
Compare
Pardon my ignorance, I am pretty sure we discussed this but I don't see it recorder here - what was the issue with introducing |
|
I don't think there's an issue with that. (Besides the name. We need a good name.) If you think that's a reasonable way forward, I'll try to figure something out. |
It does sound reasonable to me, but we can discuss it further in the mtg today (assuming you are coming). |
|
@Ladicek @Azquelt based on our discussion during the mtg, I checked for It should therefore be safe to conclude that the synthetic IPs we are discussing here should not trigger the event either. |
|
For an unexplainable reason, I'm quite fond of the idea of |
Sure, works for me. |
|
Users can also obtain the injection point via:
If we allow synthetic beans to have an If we really want to guarantee that the user cannot get an If we don't do that, I can't see how we could avoid altering |
Right, you'd only be getting regular IPs here until now, or empty collections for synth beans (excepting some edge cases where a synth. bean would "mimic" actual IP for the sake of validation which has no real use).
I am not sure I understand how would you need to see the new IP here? Or you mean to use it in place of the current method? |
|
I was thinking it would be quite acceptable to do a small breaking change and say that |
I was looking around and I didn't really find good explanation of what is this particular spec part about.
It has nothing to do with checking bean availability, we can do that with just type and qualifier and knowing which beans are enabled where. So it is likely meant to support the last bullet point:
But how does it help there? |
bc1874b to
f657c84
Compare
23493ca to
f96f107
Compare
api/src/main/java/jakarta/enterprise/inject/build/compatible/spi/SyntheticInjections.java
Outdated
Show resolved
Hide resolved
api/src/main/java/jakarta/enterprise/inject/build/compatible/spi/SyntheticInjections.java
Outdated
Show resolved
Hide resolved
api/src/main/java/jakarta/enterprise/inject/build/compatible/spi/SyntheticBeanBuilder.java
Show resolved
Hide resolved
|
Just FYI, my force-pushes recently didn't change anything in this PR, I just rebased on latest |
f96f107 to
d071996
Compare
|
Rebased and force-pushed and fixed 2 small issues. |
|
Right now, I'm thinking we actually don't need to solve the bridge from Hence, marking as ready. |
|
Just for the record, I'm aware that the suggestion in my previous comment may lead to an unspecified situation when someone obtains the |
👍 |
|
Technically the only problematic method is I have an idea how we could accomplish |
|
I added an experiment with custom IPs on custom Beans here: https://github.com/Ladicek/custom-bean-ips It seems |
d071996 to
5696ff1
Compare
|
Rebased. I believe this is ready for merging, now that #931 is merged. |
manovotn
left a comment
There was a problem hiding this comment.
I also wanted to ask whether you think we should mention this API in the spec doc itself (probably spi_lite.asciidoc)?
I know we currently don't describe the SyntheticBeanBuilder in any real detail and I don't insist on it, just wanted to know if leaving it out was intentional.
api/src/main/java/jakarta/enterprise/inject/build/compatible/spi/SyntheticBeanCreator.java
Outdated
Show resolved
Hide resolved
api/src/main/java/jakarta/enterprise/inject/build/compatible/spi/SyntheticInjections.java
Outdated
Show resolved
Hide resolved
Injection points are registered on a `SyntheticBeanBuilder` using `withInjectionPoint()`. The synthetic bean creation/destruction functions can look up injectable references for registered injection points from `SyntheticInjections`. The `SyntheticBeanCreator` and `SyntheticBeanDisposer` interfaces used to have one method. That method is now deprecated for removal and a second method is added. The second method no longer has an `Instance<Object>` parameter for arbitrary lookups; instead, is has a parameter of type `SyntheticInjections` for pre-registered injections.
5696ff1 to
f0b8d8b
Compare
|
Added a short mention of injection points to |
| * {@code SyntheticBeanBuilder.withInjectionPoint()}. All {@code @Dependent} bean instances obtained from | ||
| * {@code SyntheticInjections} during execution remain managed until the synthetic bean instance is destroyed. | ||
| * Therefore, implementations are encouraged to destroy unneeded {@code @Dependent} bean instances obtained | ||
| * from {@code SyntheticInjections}. |
There was a problem hiding this comment.
How do implementations destroy unneeded @Dependent instances? Should SyntheticInjections have a destroy method?
There was a problem hiding this comment.
Great point. Let me think about that...
There was a problem hiding this comment.
I pushed a small commit with my proposal. I removed this sentence, because the set of beans provided by SyntheticInjections is bounded (pre-defined by SyntheticBeanBuilder) and so we don't really have to care that much. The SyntheticInjections javadoc now says:
All
@Dependentbean instances created bySyntheticInjectionsare destroyed when the corresponding synthetic bean instance is destroyed.
| /** | ||
| * Contains injectable references for injection points registered for a synthetic bean. | ||
| * A synthetic bean creation/destruction function can look up beans in this container | ||
| * that were previously registered using {@code SyntheticBeanBuilder.withInjectionPoint()}. | ||
| * | ||
| * @since 5.0 | ||
| */ | ||
| public interface SyntheticInjections { |
There was a problem hiding this comment.
"Contains injectable references" suggests that the injectable references for injection points are always created prior to bean creation, which would in turn suggest that any @Dependent scoped beans are always created, even if they're never retrieved by the user.
Is this actually the case?
If not, I suggest changing the wording to "Provides injectable references".
There was a problem hiding this comment.
We don't really specify whether the injectable references are created eagerly or lazily, and I think that's on purpose. I agree that "provides" is a better verb than "contains", for sure.
…shed before merging
|
Good point made by @Azquelt on the CDI call today: we currently don't have an equivalent of |
Injection points are registered on a
SyntheticBeanBuilderusingwithInjectionPoint(). The synthetic bean creation/destruction functions can look up injectable references for registered injection points fromSyntheticInjections.The
SyntheticBeanCreatorandSyntheticBeanDisposerinterfaces used to have one method. That method is now deprecated for removal and a second method is added. The second method no longer has anInstance<Object>parameter for arbitrary lookups; instead, is has a parameter of typeSyntheticInjectionsfor pre-registered injections.Fixes #957