1. INTRODUCTION

Best-practices are discussed.
See the javadoc, starting with DiscoverySingleton and DiscoverClass,
for detail on the API:
where service implementations are looked for,
the order in which those places are checked,
which classloaders are used,
and the order in which they are used.

2. DISCOVERY SERVICES

3. ADDITIONAL TOOLS

3.1. CALLING DIRECTLY

3.1.1. Finding Singleton Instances (Factories)

DiscoverSingleton finds, loads, and manages the lifecycle of a class implementing
a given interface. It only supports classes with default (zero-argument) constructors.
DiscoverSingleton can pass a set of properties to the class
(see [Service Life Cycle Management]).
Use of the term singleton should be applied loosely:
DiscoverSingleton will instantiate separate instances of a class if called with
different:

DiscoverSingleton looks for the value of the system property
org.apache.commons.logging.LogFactory
for the name of a class that implements the LogFactory (abstract) class.
Failing that, it uses JDK1.3-style service discovery.

DiscoverSingleton also allows a java.util.Properties
parameter to be used for query for service implementation class name,
as well as a default implementation class name:

This last form is equivalent in function
to the original LogFactory.getFactory()
method.

There are a variety of find methods
provided by DiscoverSingleton, review the javadoc for
other forms and options available.

3.1.2. Finding Classes

DiscoverClass finds and loads a class implementing a given interface.
DiscoverClass can pass a set of properties to the class if it implements
the Service interface (which doesn't support full-lifecycle
management as does the SingletonService interface).

DiscoverClass provides API's that instantiate a class, though it currently
supports only classes with default (zero-argument) constructors.
Unlike DiscoverySingleton, class instances are not cached,
so each call will result in a new object instance.

DiscoverClass is more oriented toward calling multiple times within similar contexts,
so it's use is slightly different than DiscoverSingleton: where as DiscoverSingleton provides
a set of static methods (no state), DiscoverClass must be instantiated before it is
used and maintains internal state.

In this case, DiscoverClass looks for the value of the system property
org.apache.commons.logging.LogFactory
for the name of a class that implements the LogFactory (abstract) class.
Failing that, it uses JDK1.3-style service discovery.

To find all the SPI implementation classes from user-code, use DiscoverClasses instead:

As with DiscoverSingleton, DiscoverClass provides methods that
use java.util.Properties and a default implementation class name
to help determine the name of the class.

3.2 INTEGRATING INTO FACTORIES : WRAPPING

In this example, a factory (such as is used in commons-logging)
internalizes the discovery mechanism, passing appropriate defaults
for a default properties file and a default implementation.
In this case, the factory plays double duty as both the service
to be discovered (abstract class), and the discovery mechanism.

Note the addition of one extra parameter to the find
method call.
The first parameter is a root wrapper class,
which delegates to the discovery mechanism.
This is necessary to all Discovery
to determine the correct class loaders to be used
in loading an implementation class.
The second parameter is the service interface/class
for which Discovery will be looking for an implementation.
In this example, they are the same class, as the LogFactory
is providing helper methods that 'wrap' Discovery.

3.3 INTEGRATING INTO DI FRAMEWORKS : GOOGLE GUICE

Sometimes, a DiscoverSingleton/Factory approach like the one exposed above,
is not enough, because you may require injecting dependencies in your discovered SPI.

In this example is shown how DiscoverClass can be useful inside DI framework such
Google Guice:

Apache Commons, Apache Commons Discovery, Apache, the Apache feather logo, and the Apache Commons project logos are trademarks of The Apache Software Foundation.
All other marks mentioned may be trademarks or registered trademarks of their respective owners.