Guiced Injection
libraries purpose is to enable sorted module loading, as well as provide lifecycle SPI's to manage pre-startup, module execution order, and post startup.
The injector is started/referenced using GuiceContext.inject()
.
The object GuiceContext
does provide some easy get() methods that link through to the injector
A GuicedEE Module is defined using the IGuiceModule
interface, and then providing the class in your module-info.java
file.
module my.new.rest.program { provides IGuiceModule with NewGuiceModule; provides IGuicePostStartup with NewPostStartup; provides IGuicePreStartup with NewPreStartup; provides IGuiceConfigurator with NewStartupConfigurator; provides IGuiceDestroy with NewDestroyStuff; }A module might look something like this.
Remember, everything is typesafe. So-much-so that you will get a compile error for not being compliant :)
public class ObjectMapperBinder extends AbstractModule implements IGuiceModule<ObjectMapperBinder> { public void configure() { }An application using this might have the following somewhere, depending on where it should be started
public static void main(String[] args) { GuiceContext.inject(); }
Logging
All internal logs are created via thecom.guicedee.logging.LogFactory
class. This factory prefixes all the logs with com.guicedee.
You can also use any of the common logging libraries made available with module-info's
Sorting Modules
Most* GuicedEE interfaces implementIDefaultService
This interface implements Comparator, and Comparable, and provides the necessary types for comparison.
The method
sortOrder()
is overriden where the default is 100
The interface also provides convenience methods for accessing/caching ServiceLoaders, and returning TreeSets. This allows for clean unit tests, and no mocking.
Testing
Tests will all work as you define them, but as a noteJDK 12 and up now requires that test providers are specified in the module-info as the meta-inf/services directory is no longer referenced for this information. Since we really don't want to include testing modules in our info's, you can add modules to the load cycle dynamically using GuiceContext.
GuiceContext.instance().loadIGuiceModules() GuiceContext.instance().loadIGuiceConfigs() GuiceContext.instance().loadPostStartupServices() GuiceContext.instance().loadPreStartupServices()
Service Management
We use the caching/loading mechanism of the loaderToSet in order to load all intended provisions of services, even in test mode.You use this feature to modify and alter the services loaded and used to perform any tests of your choice
IDefaultService.loaderToSet(ServiceLoader); IDefaultService.loaderToSetNoInjection(ServiceLoader); GuiceContext.instance() .getConfig() .setServiceLoadWithClassPath(true);It is best to call this method before
GuiceContext.inject()
, perhaps in a @BeforeAll for Jupiter
Concurrency
The interfacesIGuicePreStartup IGuiceDestroy
and IGuiceModule
will always execute in sort order synchronously.
IGuicePostStartup
is executed synchronously until a group of sort orders are provided.
Groups of post-startups are executed in parallel using
Executors.newWorkStealingPool()
The time to wait is set on GuiceContext
public static void main(String[] args) { GuiceContext.defaultWaitTime = 200; GuiceContext.defaultWaitUnit = TimeUnit.MILLISECONDS; GuiceContext.inject(); }
Jackson JSON Implementation
This API uses Jackson for its json implementation and structures. From 2.11.0 Jackson fully supports all modules packaged with this suite. Injections are provided for ease of use and simple access to these objectspublic class PsvmTest { @Inject private ObjectMapper objectMapper; @Inject @Named("Default") private ObjectMapper objectMapperNoConfig; @Inject @Named("JSON") private ObjectWriter objectWriter; @Inject @Named("JSONTiny") private ObjectWriter objectWriterTiny; @Inject @Named("JSON") private ObjectReader objectReader; //Changeable Keys. All internal references are via Key GuiceContext.get(DefaultObjectMapper); GuiceContext.get(JSONObjectWriter); GuiceContext.get(JSONObjectWriterTiny); GuiceContext.get(JSONObjectReader);
A few randoms
The following objects are included in the package and exposed. They do pretty much what they say.GlobalProperties can be your single @Singleton if you prefer that as your pattern
- JobService
- OptionalPair
- Pair
- GlobalProperties