AndHow Initialization

How AndHow startup up, configures itself, and your application

Initialization is AndHow's startup/bootstrap process where it does the following:

  • Discovers its own configuration

  • Discovers all declared AndHow Properties (even those in dependencies)

  • Loads values for those properties from various sources using the configured Loaders

  • Validates all property values

Within the lifecycle of your application, AndHow will initialize only once.

Implicit Initialization

Initialization can be triggered explicitly or implicitly. Implicit initialization happens as a side effect of reading a property value:

My_ANDHOW_PROPERTY.getValue();

The call to Property.getValue() forces AndHow to initialize so it can provide the value. Later calls to getValue() of any property simply return the value loaded for that property - the initialization will only ever happen once. This is the simplest way to initialze AndHow - just let it happen.

If your application could start up and not read any property values immediately, AndHow will not be forced to initialize and your configuration values would not be verified. In that case, you should use explicit initialization.

Explicit Initialization

Explicit initialization happens when your application code directly constructs the AndHow instance. We could extend the GettingStarted example to load property values from the String[] args passed to the main method by explicitly initiating AndHow in the main method:

  public static void main(String[] args) {
    AndHow.findConfig().setCmdLineArgs(args);
    
    AndHow.instance();    //  <-- Initialize

    Thread.sleep(1000000);
    checkForTaskToDo();    //  <-- Configuration is first read here
  }

In this hypothetical example, configuration values are not used until there is a task to do, perhaps long after the process has started. To ensure configuration values are validated at startup, use AndHow.instance() to force initialization of the AndHow singleton. This ensures that any mis-configuration fails fast.

Later calls to AndHow.instance() will return the single AndHow instance. Later calls to Property.getValue() will internally call AndHow.instance() to look up the property value.

In the example above, the call to AndHow.findConfig() does not cause AndHow to initialize. Instead, it retrieves the configuration that AndHow will use during initialization. Calling AndHow.findConfig() is only allowed before AndHow is initialized.

Attempting to reconfigure AndHow will throw a RuntimeException

Here is another initialization example:

  public class LambdaHandler {
    public void prepare() {
      System.out.println(A_PROP.getValue());
    }
    
    public String handle(String request) {
      AndHow.findConfig().addFixedValue(MY_ANDHOW_PROP, "xxx");
    }
  }

In the code snippets above, it looks like the intent is to set a fixed value of "xxx" for A_PROP, but perhaps prepare() is called before that happens!? In that case, A_PROP might have the 'wrong' value.

AndHow protects against this situation by blocking access to AndHow.findConfig() after initialization happens. If prepare() is called before handle(), implicit initialization happens at A_PROP.getValue(). Later when AndHow.findConfig() is called, AndHow throws a RuntimeException.

Best Practice: If your application needs to configure AndHow, use an AndHowInit class

Alternatively, ensure the application has a well defined application entry point.

See Configuring AndHow for more details.

, which is always discovered and invoked during initialization, even if implicitly initiated.

AndHow Initialization Steps in Detail

AndHow will use the StdConfig to configure itself, which is an instance of AndHowConfiguration, unless there is an implementation of AndHowInit is on the classpath. AndHowInit is an interface with a single method: getConfiguration() which returns AndHowConfiguration. Common initiation needs, like injecting String[] args or adding fixed values can be handled in-line with explicit initiation (example above). For more detailed control, subclassing StdConfig and providing an AndHowInit implementation is needed.

Last updated