org.apache.commons.discovery.tools

Class DiscoverSingleton


public class DiscoverSingleton
extends java.lang.Object

Discover singleton service providers. This

DiscoverSingleton instances are cached by the Discovery service, keyed by a combination of

This DOES allow multiple instances of a given singleton class to exist for different class loaders and different group contexts.

In the context of this package, a service interface is defined by a Service Provider Interface (SPI). The SPI is expressed as a Java interface, abstract class, or (base) class that defines an expected programming interface.

DiscoverSingleton provides the find methods for locating and instantiating a singleton instance of an implementation of a service (SPI). Each form of find varies slightly, but they all perform the same basic function. The simplest find methods are intended for direct use by components looking for a service. If you are not sure which finder(s) to use, you can narrow your search to one of these:

The DiscoverSingleton.find methods proceed as follows:

  • If the name of the implementation class is non-null, load that class. The class loaded is the first class loaded by the following sequence of class loaders: An exception is thrown if the class cannot be loaded.
  • If the name of the implementation class is null, AND the default implementation class (defaultImpl) is null, then an exception is thrown.
  • If the name of the implementation class is null, AND the default implementation class (defaultImpl) is non-null, then load the default implementation class. The class loaded is the first class loaded by the following sequence of class loaders:

    This limits the scope in which the default class loader can be found to the SPI, DiscoverSingleton, and System class loaders. The assumption here is that the default implementation is closely associated with the SPI or system, and is not defined in the user's application space.

    An exception is thrown if the class cannot be loaded.

  • Verify that the loaded class implements the SPI: an exception is thrown if the loaded class does not implement the SPI.
  • Create an instance of the class.
  • Variances for various forms of the find methods are discussed with each such method. Variances include the following concepts:

  • groupContext - differentiates service providers for different logical groups of service users, that might otherwise be forced to share a common service and, more importantly, a common configuration of that service.

    The groupContext is used to qualify the name of the property file name: groupContext + '.' + propertiesFileName. If that file is not found, then the unqualified propertyFileName is used.

    In addition, groupContext is used to qualify the name of the system property used to find the service implementation by prepending the value of groupContext to the property name: groupContext> + '.' + SPI.class.getName(). Again, if a system property cannot be found by that name, then the unqualified property name is used.

  • IMPLEMENTATION NOTE - This implementation is modelled after the SAXParserFactory and DocumentBuilderFactory implementations (corresponding to the JAXP pluggability APIs) found in Apache Xerces.

    Version:
    $Revision: 480374 $ $Date: 2006-11-28 19:33:25 -0800 (Tue, 28 Nov 2006) $
    Authors:
    Richard A. Sitze
    Craig R. McClanahan
    Costin Manolache

    Method Summary

    static Object
    find(Class spiClass)
    Find implementation of SPI.
    static Object
    find(Class spiClass, Properties properties)
    Find implementation of SPI.
    static Object
    find(Class spiClass, Properties properties, String defaultImpl)
    Find implementation of SPI.
    static Object
    find(Class spiClass, String defaultImpl)
    Find implementation of SPI.
    static Object
    find(Class spiClass, String propertiesFileName, String defaultImpl)
    Find implementation of SPI.
    static Object
    find(ClassLoaders loaders, SPInterface spi, PropertiesHolder properties, DefaultClassHolder defaultImpl)
    Find implementation of SPI.
    static void
    release()
    Release all internal references to previously created service instances associated with the current thread context class loader.
    static void
    release(Class spiClass)
    Release any internal references to a previously created service instance associated with the current thread context class loader.

    Method Details

    find

    public static Object find(Class spiClass)
                throws DiscoveryException
    Find implementation of SPI.
    Parameters:
    spiClass - Service Provider Interface Class.
    Returns:
    Instance of a class implementing the SPI.
    Throws:
    DiscoveryException - Thrown if the name of a class implementing the SPI cannot be found, if the class cannot be loaded and instantiated, or if the resulting class does not implement (or extend) the SPI.

    find

    public static Object find(Class spiClass,
                              Properties properties)
                throws DiscoveryException
    Find implementation of SPI.
    Parameters:
    spiClass - Service Provider Interface Class.
    properties - Used to determine name of SPI implementation, and passed to implementation.init() method if implementation implements Service interface.
    Returns:
    Instance of a class implementing the SPI.
    Throws:
    DiscoveryException - Thrown if the name of a class implementing the SPI cannot be found, if the class cannot be loaded and instantiated, or if the resulting class does not implement (or extend) the SPI.

    find

    public static Object find(Class spiClass,
                              Properties properties,
                              String defaultImpl)
                throws DiscoveryException
    Find implementation of SPI.
    Parameters:
    spiClass - Service Provider Interface Class.
    properties - Used to determine name of SPI implementation, and passed to implementation.init() method if implementation implements Service interface.
    defaultImpl - Default implementation.
    Returns:
    Instance of a class implementing the SPI.
    Throws:
    DiscoveryException - Thrown if the name of a class implementing the SPI cannot be found, if the class cannot be loaded and instantiated, or if the resulting class does not implement (or extend) the SPI.

    find

    public static Object find(Class spiClass,
                              String defaultImpl)
                throws DiscoveryException
    Find implementation of SPI.
    Parameters:
    spiClass - Service Provider Interface Class.
    defaultImpl - Default implementation.
    Returns:
    Instance of a class implementing the SPI.
    Throws:
    DiscoveryException - Thrown if the name of a class implementing the SPI cannot be found, if the class cannot be loaded and instantiated, or if the resulting class does not implement (or extend) the SPI.

    find

    public static Object find(Class spiClass,
                              String propertiesFileName,
                              String defaultImpl)
                throws DiscoveryException
    Find implementation of SPI.
    Parameters:
    spiClass - Service Provider Interface Class.
    propertiesFileName - Used to determine name of SPI implementation, and passed to implementation.init() method if implementation implements Service interface.
    defaultImpl - Default implementation.
    Returns:
    Instance of a class implementing the SPI.
    Throws:
    DiscoveryException - Thrown if the name of a class implementing the SPI cannot be found, if the class cannot be loaded and instantiated, or if the resulting class does not implement (or extend) the SPI.

    find

    public static Object find(ClassLoaders loaders,
                              SPInterface spi,
                              PropertiesHolder properties,
                              DefaultClassHolder defaultImpl)
                throws DiscoveryException
    Find implementation of SPI.
    Parameters:
    spi - Service Provider Interface Class.
    properties - Used to determine name of SPI implementation, and passed to implementation.init() method if implementation implements Service interface.
    defaultImpl - Default implementation.
    Returns:
    Instance of a class implementing the SPI.
    Throws:
    DiscoveryException - Thrown if the name of a class implementing the SPI cannot be found, if the class cannot be loaded and instantiated, or if the resulting class does not implement (or extend) the SPI.

    release

    public static void release()
    Release all internal references to previously created service instances associated with the current thread context class loader. The release() method is called for service instances that implement the Service interface. This is useful in environments like servlet containers, which implement application reloading by throwing away a ClassLoader. Dangling references to objects in that class loader would prevent garbage collection.

    release

    public static void release(Class spiClass)
    Release any internal references to a previously created service instance associated with the current thread context class loader. If the SPI instance implements Service, then call release().

    Copyright (c) 2002 - Apache Software Foundation