As mentioned in the introduction, the BeanContext
API also provides a
standard mechanism through which JavaBeans can discover and utilize the
services offered by their enclosing BeanContext
.
Service capability is defined by the
BeanContextServices
interface. Because this interface is a BeanContext
extension, it inherits all
BeanContext
membership capabilities.
The discovery and
requesting of services can be summarized in the following steps:
java.beans.beancontext.BeanContextServicesListener
interface joins the bean context (the context itself
is a BeanContextServices
implementation),
and registers its intent to be notified of new services via the context's
addBeanContextServicesListener(BeanContextServicesListener bcsl)
method.
java.beans.beancontext.BeanContextServiceProvider
registers
a new service with the context via the
context's addService()
method. The context notifies
all currently registered listeners that this new service has been added.
BeanContextServices: Service Related Methods
java.beans.beancontext.BeanContextServicesSupport
object as the bean context, it is possible to:
BeanContext
:
boolean addService(java.lang.Class serviceClass, BeanContextServiceProvider serviceProvider)
BeanContext
:
boolean addService(Class serviceClass, BeanContextServiceProvider bcsp, boolean fireEvent)
void revokeService(java.lang.Class serviceClass, BeanContextServiceProvider serviceProvider, boolean revokeCurrentServicesNow)
BeanContextChild
's (or any arbitrary object associated with a BeanContextChild
) reference to the specified service:
void releaseService(BeanContextChild child, java.lang.Object requestor, java.lang.Object service)
BeanContextServicesListener
void addBeanContextServicesListener(BeanContextServicesListener bcsl)
BeanContextServicesListener
:
void removeBeanContextServicesListener(BeanContextServicesListener bcsl)
Iterator getCurrentServiceClasses()
boolean hasService(java.lang.Class serviceClass)
Object getService(BeanContextChild child, java.lang.Object requestor, java.lang.Class serviceClass, java.lang.Object serviceSelector, BeanContextServiceRevokedListener bcsrl)
Iterator getCurrentServiceSelectors(java.lang.Class serviceClass)
JavaBeans nested into a BeanContextServices
implement BeanContextServicesListener
to listen for new services
being added, and/or BeanContextServiceRevokedListener
to listen for services being revoked.
There are two event types that may be intercepted by such listeners:
BeanContextServiceAvailableEvent
: received by the BeanContextServicesListener
in
order to identify the service being registered.
BeanContextServiceRevokedEvent
: received by the
BeanContextServiceRevokedListener
in order to identify the
service being revoked.
JavaBeans can query their enclosing bean context for a list of available services, or ask for a specific service
by name. The service itself, however, is actually delivered by a BeanContextServiceProvider
.
The provider can be any object that implements the
java.beans.beancontext.BeanContextServiceProvider
interface. Services
become available in a context via the bean context's addService() registration method.
BeanContextServiceProvider offers the following three methods, which will be automatically called when a bean requests (or releases) a service from its context:
Object getService(BeanContextServices bcs, java.lang.Object requestor, java.lang.Class serviceClass, java.lang.Object serviceSelector)
Iterator getCurrentServiceSelectors(BeanContextServices bcs, java.lang.Class serviceClass)
public void releaseService(BeanContextServices bcs, java.lang.Object requestor, java.lang.Object service)
Release a service from any object that currently has a reference to it
The service itself is best described by this paragraph from the specification:
A service, represented by a Class object, is typically a reference to either an interface, or to an implementation that is not publicly instantiable. This Class defines an interface protocol or contract between a BeanContextServiceProvider, the factory of the service, and an arbitrary object associated with a BeanContextChild that is currently nested within the BeanContext the service is registered with.
The following section presents a sample application that uses a word counting service to count the number of words in a given text file.
DocumentBean.java
: A JavaBean that encapsulates a File
object. Create an instance of this bean by passing it
a String
indicating the name of the text file to represent. This bean extends BeanContextChildSupport
, which allows
it to listen for addition/revocation of services in its context. When the bean detects that a
WordCount
service
has been added to the context, it requests the service to count the number of words it contains.
WordCountServiceProvider.java
: A class that acts as the
factory for delivering the WordCount
service. This
class implements the BeanContextServiceProvider
interface.
WordCount.java
: This interface defines the service itself.
DocumentTester.java
: The main test program.
File:
DocumentBean.java
import java.beans.beancontext.*; import java.io.*; import java.util.*; public final class DocumentBean extends BeanContextChildSupport { private File document; private BeanContextServices context; public DocumentBean(String fileName) { document = new File(fileName); } public void serviceAvailable(BeanContextServiceAvailableEvent bcsae) { System.out.println("[Detected a service being added to the context]"); // Get a reference to the context BeanContextServices context = bcsae.getSourceAsBeanContextServices(); System.out.println("Is the context offering a WordCount service? " + context.hasService(WordCount.class)); // Use the service, if it's available if (context.hasService(WordCount.class)) { System.out.println("Attempting to use the service..."); try { WordCount service = (WordCount)context.getService(this, this, WordCount.class, document, this); System.out.println("Got the service!"); service.countWords(); } catch(Exception e) { } } } public void serviceRevoked(BeanContextServiceRevokedEvent bcsre) { System.out.println("[Detected a service being revoked from the context]"); } }
File:
WordCountServiceProvider.java
import java.beans.beancontext.*; import java.util.*; import java.io.*; public final class WordCountServiceProvider implements BeanContextServiceProvider { public Object getService(BeanContextServices bcs, Object requestor, Class serviceClass, Object serviceSelector) { // For this demo, we know that the cast from serviceSelector // to File will always work. final File document = (File)serviceSelector; return new WordCount() { public void countWords() { try { // Create a Reader to the DocumentBean's File BufferedReader br = new BufferedReader(new FileReader(document)); String line = null; int wordCount = 0; while ((line = br.readLine()) != null) { StringTokenizer st = new StringTokenizer(line); while (st.hasMoreTokens()) { System.out.println("Word " + (++wordCount) + " is: " + st.nextToken()); } } System.out.println("Total number of words in the document: " + wordCount); System.out.println("[WordCount service brought to you by WordCountServiceProvider]"); br.close(); } catch(Exception e) { } } }; } public void releaseService(BeanContextServices bcs, Object requestor, Object service) { // do nothing } public Iterator getCurrentServiceSelectors(BeanContextServices bcs, Class serviceClass) { return null; // do nothing } }
File:
WordCount.java
public interface WordCount { public abstract void countWords(); }
File:
DocumentTester.java
import java.beans.beancontext.*; import java.util.*; public class DocumentTester { public static void main(String[] args) { BeanContextServicesSupport context = new BeanContextServicesSupport(); // a bean context DocumentBean doc1 = new DocumentBean("Test.txt"); context.add(doc1); context.addBeanContextServicesListener(doc1); // listen for new services WordCountServiceProvider provider = new WordCountServiceProvider(); context.addService(WordCount.class, provider); // add the service to the context } }
File:
Test.txt
This text will be analyzed by the WordCount service.
[Detected a service being added to the context] Is the context offering a WordCount service? true Attempting to use the service... Got the service! Word 1 is: This Word 2 is: text Word 3 is: will Word 4 is: be Word 5 is: analyzed Word 6 is: by Word 7 is: the Word 8 is: WordCount Word 9 is: service. Total number of words in the document: 9 [WordCount service brought to you by WordCountServiceProvider]