Because Geotools core API consists almost exclusively of interfaces (including GeoAPI), factories play a role in how developers use the API. Although the interfaces that are declared in GeoAPI are implemented in various Geotools packages you should not use those classes directly. Instead you should use factories.
J2SE's {@link javax.imageio.spi.ServiceRegistry} provides a general way (even if it is defined in a {@code javax.imageio} subpackage) to instantiate and manage factories (also called providers). Each factory implementation should be declared in {@code META-INF/services} directory, usually bundled in every JAR file. For example if a JAR file provides one or more {@link org.opengis.referencing.datum.DatumFactory} implementations, then it must provide the following file:
META-INF/services/org.opengis.referencing.datum.DatumFactory
with a content similar to the one below:
com.mycompany.MyDatumFactory1 com.mycompany.MyDatumFactory2 com.mycompany.MyDatumFactory3
The ordering is initially unspecified. Users can {@linkplain javax.imageio.spi.ServiceRegistry#setOrdering set an ordering} explicitly themselves, or implementations can do that automatically {@linkplain javax.imageio.spi.RegisterableService#onRegistration on registration}. The {@link org.geotools.factory.AbstractFactory} class provides a simple way to setup ordering on registration on the basis of a {@linkplain org.geotools.factory.AbstractFactory#priority priority} number.
If a user wants a specific implementation, he can {@linkplain javax.imageio.spi.ServiceRegistry#getServiceProviders iterates through registered ones} and pickup the desired implementation himself. An alternative is to bundle the criterions in a {@linkplain org.geotools.factory.Hints map of hints} and lets the registry selects an implementation accordingly. This later functionality is not provided by the standard {@link javax.imageio.spi.ServiceRegistry}, but is provided by Geotools's {@link org.geotools.factory.FactoryRegistry} extension. This class extends the service registry API with the following functionalities:
A {@link org.geotools.factory.FactoryRegistry#scanForPlugins() scanForPlugins()} method that scans for plugins in the {@linkplain java.lang.Class#getClassLoader registry class loader}, the {@linkplain java.lang.Thread#getContextClassLoader thread context class loader} and the {@linkplain java.lang.ClassLoader#getSystemClassLoader system class loader}. Additionally, {@code scanForPlugins()} looks for any implementation specified as {@linkplain java.lang.System#getProperty(String) system property}.
Filters out automatically {@linkplain org.geotools.factory.OptionalFactory optional factories} when they are not {@linkplain org.geotools.factory.OptionalFactory#isAvailable available}.
When more than one implementation is available for the same {@link org.geotools.factory.Factory} subinterface, an optional set of {@linkplain org.geotools.factory.Hints hints} can specifies the criterions that the desired implementation must meets. If a factory implementation depends on other factories, the dependencies hints are checked recursively.
Optionally, if no factory matches the given hints, a new instance can be {@linkplain org.geotools.factory.FactoryCreator#createServiceProvider automatically created}.
Note that the {@linkplain org.geotools.factory.Hints hints}, if provided, don't need to apply directly to the requested factory category. They may apply indirectly through some dependency. A typical example is a request for any {@link com.vividsolutions.jts.geom.GeometryFactory} instance, providing that this instance uses a particular {@link com.vividsolutions.jts.geom.CoordinateSequenceFactory} implementation.