Substrate
@Provided
The interfaces defined within Substrates API are designed with extensibility and evolution in mind, both from a client library and provider implementation perspective. Extensibility starts with the Substrate interface, a foundational interface extended by all interfaces annotated with @Provided, that defines a single method, named environment, that returns an Environment instance.
1 2 3 4 5 6 7 8 9 10 11 |
@Abstract public interface Substrate { default Environment environment () { return Environment.EMPTY; } } |
Environment
Lookup
The Environment interface, originally designed to allow for interfacing with existing configuration stores and systems, offers a standard way for implementation providers to expose additional extension properties to each of the @Provided annotated interfaces.
The Environment interface extends the Lookup interface with additional type-specific methods for common class types, such as Integer, Long, String, Double, Boolean, etc., where typed values are accessed using a predefined Name, think of a key into a map structure, that can be specified in a provider’s supporting documentation or published within a utility class or interface.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
@Abstract public interface Lookup < T > { default Optional< T > get ( final Name name ) { return ofNullable ( get ( name, null ) ); } T get ( Name name, T defValue ); } |
A benefit of this design choice is that the surface area of the interfaces that extend the Substrate interface can be kept to a bare minimum, a “least common denominator” set of properties and operations across all implementations of the Substrates API, while still allowing for the environment-, configuration-, provider-, runtime-specific state of being publically accessible without impacting the ability of a client codebase (agent, application, plugin) to move from one implementation provider to another.
Variable
Cortex
Using the Variable interface is recommended when working with the Environment interface in repeatedly looking up a particular named value as a provider can optimize the underlying internal implementation, such as adding caching and short-circuiting code paths.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
@Utility @Provided public interface Variable < T > extends Substrate { T of ( final Environment environment ); default T of ( final Substrate substrate ) { return of ( substrate .environment () ); } } |
The Cortex interface, the Substrates API root fabrication runtime component, offers various overloaded methods to create a type-specific Variable instance, such as specifying a default value when a lookup does not succeed and a transformation when it does.
1 2 3 4 5 6 |
Variable< Long > variable ( final Name name, final Long defValue ) |