maintains contextual information for a thread in a set of {@link Context}s.
Introduction
Objects have different lifecycles and different context's (aka scopes). An environment provides the structure to easily manage objects with different contexts.
Examples of contexts are:
- application: The application context is used to store e.g. data sources, session factories and other static resources needed by an application. The application context lives for the complete duration of the {@link EnvironmentFactory}. So if the {@link EnvironmentFactory} is maintained in a static member field, the application context lives for the duration of the application. The same application context is shared for all the Environments produced by one EnvironmentFactory.
- block: The block context is used for e.g. a transaction and transactional resources, user authentication. In combination with a {@link WireContext}, this results in an efficient and configurable use of transactional resources that need to be lazily initialized.
- The environment can accomodate other contexts as well. They can be added and removed dynamically. Examples of other potential contexts are web-request, web-session, web-application, business processDefinition, job, ...
An environment is typically installed like this
static EnvironmentFactory environmentFactory = new DefaultEnvironmentFactory(); ... Environment environment = environmentFactory.openEnvironment(); try { ... everything available in this block ... } finally { environment.close(); }
Purpose
The first purpose of the environment is to separate the application from the environment. Standard Java and Enterprise Java are quite different and an environment abstraction like this allows for the development of applications that can run in both Standard and Enterprise environments. Also test environments are easier to tweak this way.
A second purpose of the environment is to enable specific to global searching of resources. E.g. you could search for an 'adminEmailAddress' in the contexts 'processDefinition-execution', 'processDefinition-definition' and 'application' in the given order. That way, a global adminEmailAddress can be specified in the application context and it can be refined in more specific contexts processDefinition-definition or processDefinition-execution.
Search order
To find an object in the environment, a searchOrder can be specified. A search order is an sequence that specifies the order in which the contexts should be searched.
The default search order is the inverse sequence of how the contexts are added to the environment. This is because in general, we can assume that the more recent a context was added, the more specific it is.
Transaction, username and classloader
Three objects are used so frequently in an environment that they get special treatment:
- Transaction: an abstraction for marking a transaction with setRollbackOnly.
- Classloader: the current class loader.
- Username: the name of the currently authenticated user.
For these special properties, setters are also available. That is to support programmatic injection into the environment. Alternatively, they can be configured in one of the contexts.
@see EnvironmentFactory
@author Tom Baeyens