GuicedEE Inject
The runtime engine that classpath-scans, creates the Guice injector, and manages the full startup/shutdown lifecycle.
Core Concept
GuiceContext is a singleton that orchestrates everything. Call inject() once — it discovers SPIs, scans, builds the injector, and runs lifecycle hooks:
IGuiceConfigurator → ClassGraph scan → IGuicePreStartup → Injector created → IGuicePostStartup
↓
IGuicePreDestroy (shutdown)
Required Flow
- Add
com.guicedee:injectdependency. - Register your module for scanning, then bootstrap:
IGuiceContext.registerModuleForScanning.add("my.app"); IGuiceContext.instance().inject(); - Configure
module-info.java:requires com.guicedee.guicedinjection;opensinjection packages tocom.google.guiceopensDTO packages tocom.fasterxml.jackson.databindprovidesevery SPI implementation
- Dual-register all SPIs in
module-info.javaandMETA-INF/services/.
Providing Guice Modules
Implement IGuiceModule and register via SPI:
public class AppModule extends AbstractModule implements IGuiceModule<AppModule> {
@Override
protected void configure() {
bind(Greeter.class).to(DefaultGreeter.class);
}
}
// module-info.java
provides com.guicedee.client.services.lifecycle.IGuiceModule with my.app.AppModule;
Lifecycle Hooks
| Hook | When it runs | Return |
|---|---|---|
| IGuiceConfigurator | First — configures GuiceConfig before scanning | IGuiceConfig<?> |
| IGuicePreStartup | After scan, before injector — grouped by sortOrder() | List<Future<Boolean>> |
| IGuiceModule | During injector creation — standard Guice module | — |
| IGuicePostStartup | After injector is ready — async, grouped by sortOrder() | List<Uni<Boolean>> |
| IGuicePreDestroy | On shutdown — cleanup resources | void |
All hooks extend IDefaultService<J> (CRTP); override sortOrder() to control execution order and enabled() to conditionally skip.
Logging
LogUtils — programmatic setup
LogUtils.addHighlightedConsoleLogger(); // ANSI console (local dev)
LogUtils.addConsoleLogger(Level.INFO); // plain console
LogUtils.addFileRollingLogger("app", "logs"); // rolling file (100 MB / daily)
Logger audit = LogUtils.getSpecificRollingLogger("audit", "logs/audit", null, false);
When CLOUD env var is set, layouts auto-switch to compact JSON.
Log level control
Set via environment: GUICEDEE_LOG_LEVEL, LOG_LEVEL, DEBUG=true, or TRACE=true.
Programmatic: GuiceContext.setDefaultLogLevel(Level.INFO).
JobService
Virtual-thread-backed executor pools with graceful shutdown:
JobService jobs = JobService.INSTANCE;
jobs.registerJob("import", 100);
jobs.addJob("import", () -> processFile(file));
jobs.registerPollingJob("heartbeat", () -> ping(), 0, 30, TimeUnit.SECONDS);
Pools auto-shutdown via IGuicePreDestroy.
Non-Negotiable Constraints
- Never call
inject()recursively during build — useIGuicePostStartupinstead. - At most one
GuiceContextinstance per JVM. - Every SPI must be dual-registered (
module-info.java+META-INF/services/). - Injection packages must
openstocom.google.guice. IGuiceContext.registerModuleForScanning.add("my.module")must be called beforeinstance().- Scanning is off by default and no built-in configurator enables it — call
IGuiceContext.instance().getConfig().setClasspathScanning(true).setAnnotationScanning(true).setMethodInfo(true).setFieldInfo(true)(orsetServiceLoadWithClassPath(true)) beforeinject(), or annotation discovery finds nothing. Tests that boot directly must do the same in@BeforeAll. - All lifecycle hooks must extend
IDefaultService<J>(CRTP) and overridesortOrder().
References
references/classpath-scanning.md— scanner SPI interfaces,GuiceConfigoptions, module/JAR/package filtering.references/lifecycle-logging.md— lifecycle hook details,@InjectLoggerattributes,LogUtilsAPI,Log4JConfiguratorSPI,JobServicefull API.