Simple Usage Examples
This page does some walk-throughs of simple code examples. You might try the Live-Code Quickstart to try using AndHow right in the browser. The Live-Code is more fun, but this page is much more comprehensive.
Complete Usage Example
// 1 : Declare AndHow Properties
StrProp
& IntProp
are AndHow Property
s. Properties and their values are constants, so they are always static final
but may be private
or any scope. Properties are strongly typed, so their value, default value and validation are type specific.
// 2 : Using AndHow Properties
Properties are used just like static final constants with .getValue()
tacked on: NAME.getValue()
returns a String
, REPEAT_COUNT.getValue()
returns an Integer
.
The Properties in the example have defaults, so with no other configuration, running HelloWorld.main()
will print Hello, Dave
twice. One way (of many) to configure values is to add an andhow.properties
file on the classpath like this:
Resulting in Hello, Kathy
x4 - AndHow ignores capitalization when reading Property values. Unlike most configuration utilities, we didn't have to specify a 'name' for NAME. AndHow builds a logical name for each property by combining the canonical name of the containing class with the variable name, e.g.:
[Java canonical class name].[AndHow Property name]
--> simple.HelloWorld.NAME
Thus, naming isn't something you have to worry about and Java itself ensures name uniqueness. Let's extends this example a bit...
Adding validation and command line arguments
// 1 : Declare AndHow Properties with validation
Property
values can have validation. At startup, AndHow discovers and validates all Properties in your entire application, ensuring that a mis-configuration application fails fast at startup, rather than mysteriously failing later.
Placing Property
's in an interface is best practice for organization and access control. Only code able to 'see' a Property
can retrieve its value - standard Java visibility rules. Fields in an interface are implicitly static final
, saving a bit of typing.
// 2 : Add command line arguments
AndHow loads Property values from several configuration sources in a well established order. At startup, AndHow scans System.Properties
, environment variables, JNDI values, the andhow.properties
file, etc., automatically.
Reading from commandline requires a bit of help from the application. The code AndHow.findConfig().setCmdLineArgs(args);
passes the command line arguments in to AndHow.
Running from cmd line to set NAME
to 'Dar' would look like this:
What happens if we try to set NAME to "Bar" and violate the 'D' validation rule? AndHow throws a RuntimeException
to stop app startup and prints a clear message about the cause:
AndHow uses Property metadata to generate precise error messages. When errors prevent startup, AndHow also creates a configuration template with all your application's Property
s, validation requirements, types, defaults and more. Here is what that would look like for this app:
You can create a configuration template on demand by setting the AHForceCreateSamples
flag: java -DAHForceCreateSamples=true -cp [classpath] simple.HelloWorld2
Let's look at a larger, more enterprise-y example.
Example with a database connection, aliases and exports
In this example, assume we need to configure an ORM framework like Hibernate. 3rd party frameworks have their own configuration property names and typically accept properties as a Map
or util.Properties
. This example is in two parts: A Handler class which might be an AWS Lambda, and a DAO (Data Access Object) which stores data to a DB using Hibernate.
// 1 : Declare configuration Property's for this class
AndHow best practice: Place Properties in the class that uses them. This makes intuitive sense and there is no need to gather them all into a central Config class - AndHow will find, load and validate them all and create a configuration template listing them all.
The TAX_RATE
Property uses .aliasIn("tax")
, which adds an alternate name recognized when reading this property from a configuration source. Handy for values that may need to be specified on cmd line.
Lets look at how the DAO class uses AndHow:
// 3 : Declare DB connection Properties
The Properties bundled together in Db
are annotated with @ManualExportAllowed
, allowing them to be exported to a Map
or other structure. .aliasInAndOut()
adds an in name just like 'tax' above, but the name is also used when exporting (out).
// 4 : Export Db properties to a java.util.Properties instance
Property exports use the Java stream()
API. Exports are done at the class level: AndHow.instance().export(class...)
specifies one or more @ManualExportAllowed
annotated classes containing AndHow Properties. ExportCollector
has collectors to turn a stream of Properties into collections: ExportCollector.stringProperties("")
turns AndHow Properties into java.util.Properties
with String values (using "" for null values).
Since we specified alias out names for the Db Properties, the Hibernate compatible aliases are used for the export. AndHow provides validation at startup, configuration from multiple sources, and more... and can do that for 3rd party frameworks!
Testing Applications with AndHow
AndHow makes testing with multiple configurations easy. Let's test the SaleHandler
from above and assume an `andhow.properties' file like this:
We can verify the tax rate is set as expected:
Now lets test the handler with the tax rate configured to 12%:
// 1 : 'Kill' the current AndHow configuration
The annotation @KillAndHowBeforeThisTest
erases AndHow's state before the test.
// 2 : Set a new configured value for TAX_RATE
AndHow.findConfig()
grabs the configuration of AndHow itself to add a 'fixed value' for TAX_RATE
, ignoring any other configured value for that property.
// 3 : Cleanup after the test
The tax rate is .12
just for this test. When the test is done, AndHow is restored to its previous state. This isn't allowed in production: Remember, AndHow Property values are constant and once initialized at startup, do not change. The @KillAndHow...
annotation uses reflection to bend the rules to make testing easy.
&?!
Last updated
Was this helpful?