-
Notifications
You must be signed in to change notification settings - Fork 81
add @Eager
#911
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
Open
Ladicek
wants to merge
2
commits into
jakartaee:main
Choose a base branch
from
Ladicek:eager-init
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
add @Eager
#911
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,47 @@ | ||
| /* | ||
| * Copyright 2025, Contributors to the Eclipse Foundation | ||
| * | ||
| * This program and the accompanying materials are made available under the | ||
| * Apache Software License 2.0 which is available at: | ||
| * https://www.apache.org/licenses/LICENSE-2.0. | ||
| * | ||
| * SPDX-License-Identifier: Apache-2.0 | ||
| */ | ||
|
|
||
| package jakarta.enterprise.context; | ||
|
|
||
| import java.lang.annotation.Documented; | ||
| import java.lang.annotation.ElementType; | ||
| import java.lang.annotation.Retention; | ||
| import java.lang.annotation.RetentionPolicy; | ||
| import java.lang.annotation.Target; | ||
|
|
||
| import jakarta.enterprise.util.AnnotationLiteral; | ||
|
|
||
| /** | ||
| * Marks the annotated bean as eagerly initialized. May be applied to a bean class, | ||
| * producer method or field or {@linkplain jakarta.enterprise.inject.Stereotype stereotype}. | ||
| * <p> | ||
| * Only {@link ApplicationScoped @ApplicationScoped} beans may be eagerly initialized. | ||
| * <p> | ||
| * Contextual instance of an eagerly initialized bean is created no later than at the moment | ||
| * the container fires the {@link jakarta.enterprise.event.Startup Startup} event. | ||
| * | ||
| * @since 5.0 | ||
| */ | ||
| @Target({ ElementType.TYPE, ElementType.METHOD, ElementType.FIELD }) | ||
| @Retention(RetentionPolicy.RUNTIME) | ||
| @Documented | ||
| public @interface Eager { | ||
| /** | ||
| * Supports inline instantiation of the {@link Eager} annotation. | ||
| */ | ||
| final class Literal extends AnnotationLiteral<Eager> implements Eager { | ||
| public static final Literal INSTANCE = new Literal(); | ||
|
|
||
| private static final long serialVersionUID = 1L; | ||
|
|
||
| private Literal() { | ||
| } | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My gut feeling is that many more people read the javadoc than read the spec so I think we should include the following information here:
Eageris equivalent to observingStartupEagermay only be used onApplicationScopedbeansEagercan be applied to a managed bean class, a producer method or a producer fieldThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're right. I had a similar text to the spec in the javadoc, but decided against it, because it's relatively dense and thick. I'll add something lighter back.
Also, this reminds me I have to add support for synthetic beans -- I had it in mind originally, but forgot. I'll fix that too.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I addressed this particular comment.
Locally, I have code that allows synthetic beans to be eagerly initialized, but I think I need to prototype an implementation at least to some extent to see whether the API I've got makes sense.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And the JavaDoc here confused me.
If the eager is inverting the lazy proxy creation. I do not think it is equivalent to
@Observes StarupEvent.It should be related to how to handle the bean instantiation. Firstly creating an empty proxy like normal, then immediately execute more steps:
@PostConstructmethod.In theory, any scoped beans could be operated like this. Even
applicationScopedbean looks more reasonable.In contrast to Spring Boot
ApplicationReadyevent, the bean initialization does not depend on it.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not sure I understand your comment but it is equivalent.
In order for CDI container to notify a bean of such an event, it first creates its instance which includes injecting into it and calling its post construct method. This is a shorthand for the same.
See the original CDI issue, it mentioned several variants but in the end we decided to start smaller and only define it for app scoped beans which are the most common usage we know/heard of.
FTR, you can achieve the same for any scope and with the addition of
BeanContainer#unwrapClientProxyit should be fairly simple.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is very much not true. As mentioned above, the only thing that
@Eagerdoes is forcing the contextual instance of the bean into existence early on. If there's another bean calling into the@Eagerbean before that eager bean was initialized (most likely because the other bean is also@Eagerand calls into the first bean from a@PostConstructcallback or something like that), the instance will be created during that call.Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, this is the nice thing about making an
@Eagerbean with a@PostConstructmethod, vs observingStartupand doing any setup logic in the observer method;@PostConstructis guaranteed to run before the bean is used, whereas observer methods are called in priority order.All that
@Eagerdoes is make sure that an instance of the bean is created when theStartupevent is fired.Would it be clearer to say this?
I can't decide if that detail is helpful to have in the Javadoc or just makes the sentence more confusing.
Edit: this might be better:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I'd rather say
Or maybe reword it more:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ideally, I think the CDI implementor has a mechanism that can track all
@Eagerbeans and make sure all are initialized successfully, then fire theStartUpEvent.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I still don't understand the difference between "immediately before
Startup" and "duringStartupat priorityInteger.MIN_VALUE", but sure, we can say "immediately before firingStartup".Aside:
Please stop calling it
StartupEventorStartUpEvent, it's calledStartup.