-
-
Notifications
You must be signed in to change notification settings - Fork 199
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
Add Avaje Inject Module #3416
Add Avaje Inject Module #3416
Conversation
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.
Good addition, thank you. Just one comment
modules/jooby-avaje-inject/src/main/java/io/jooby/avaje/inject/JoobyPropertyPlugin.java
Outdated
Show resolved
Hide resolved
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 grabbed the source and tried locally. It results in multiple Hikari re-initialisation and database connections and application crash. This is due to beanScope.provideDefault(key.getName(), key.getType(), e::getValue);
which adds the bean as secondary.
I suggest changing it to beanScope.bean(key.getType(), e.getValue());
.
With this change my testing code works, still needs @InjectModule(requires)
everywhere.
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.
Please, change service registration as follows:
if (key.getName() == null) {
beanScope.provideDefault(key.getType(), e::getValue);
} else {
beanScope.bean(key.getName(), key.getType(), e.getValue());
}
This:
- prevents adding multiple secondary beans for same type, Avaje complains about that
- allows named injection, e.g.
@Named("db1") Jdbi
ps: adding package-info.java with specific InjectModule(name = 'jooby-modules', requires = {...})
is required for pass avaje-generator compillation
@ludmiloff how's this? |
@SentryMan, this does not work, at least for me.
where my DataCache class is declared as singleton with constructor like this
My proposal above works fine, though. Should I prepare some example code for experiments? |
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.
Looks ok, and is working for me.
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.
As @jknack mentioned before, there must be an existence check in JoobyPropertyPlugin, line 30
@SentryMan, may I suggest the change like this:
return config.hasPath(property) && Objects.equals(config.getString(property), value);
modules/jooby-avaje-inject/src/main/java/io/jooby/avaje/inject/AvajeInjectModule.java
Outdated
Show resolved
Hide resolved
modules/jooby-avaje-inject/src/main/java/io/jooby/avaje/inject/AvajeInjectModule.java
Show resolved
Hide resolved
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.
@SentryMan, your latest commit about named property injection works in the following scenario:
@Inject @Named("myProp") String myProp
and the actual value is available during/after PostConstruct phase.
Constructor injection of named config item (Jooby 1 style, still good :) ) does not work, however.
Existence check in JoobyPropertyPlugin is fine.
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.
A bit of explanation about my latest comment:
constructor injection if named config item does not work because it needs to be declared as external dependency, which might be very cumbersome.
you mean with the |
Yes, this way it works, thanks. |
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 this module is already done, at least for a sort of EAP.
My notes about:
- Needs documentation
- Injecting property (incl. com.typesafe.config.Config items by name) works
- Constructor injection works
- All JoobyModule(s) currently in use are injected as Avaje Beans, named injection is also supported
- All Avaje Beans are accessible via Jooby require
- Installing AvajeInjectModule does not need a specific order in code along other Jooby modules
- Packaging my test project into a single jar produces a working deployment without any problem.
Some limitation and caveats:
- Using this module needs a package-info.java with proper InjectModule(require) clause. This is very Avaje specific.
- Config item injection is currently limited to String types or string representation (toString). Might be improved with Integer and Boolean classes, though.
- Using this module needs a special maven/gradle plugin and setup for Avaje code generation
- Using this module adds a small overhead in startup time, on my testing machine 8 cores M1, java 17, small size project with 3 other jooby modules and 200 lines of config items, cold start in dev mode - around 20ms for wiring beans at runtime (as reported by Avaje), hope this is acceptable and much better than Guice
Finally, this is ready for approval and merging, IMO.
@jknack, @SentryMan, thank you for your support.
edit:
mvc also works OTB, something like mvc(MyController.class);
when MyController is declared as a singleton bean.
This should only be required if you are running on the module-path and also happen to have custom avaje autoconfig libraries. But yeah it is what it is |
First pass at an avaje inject module
helps alleviate #3415