La localizzazione dei servizi e la relativa creazione sono operazioni complesse che possono richiedere accessi a risorse di rete.
A cosa serve
Il pattern Service Locator gestisce le operazioni di localizzazione e creazione di Business Objects occupandosi di :
"nascondere" la complessità delle operazioni di ricerca (lookup) dei servizi
fornire una modalità uniforme di lookup e creazione dei servizi
isolare le eventuali operazioni di lookup "vendor dependent"
nascondere eventuali problematiche di networking
gestire eventuali necessità di caching
concentrando così la gestione delle problematiche in un singolo punto.
Motivazione
Il pattern garantisce una modalità uniforme e semplificata di localizzazione di risorse.
Spiegazione del funzionamento
La classe ServiceLocator effettua le operazioni che permettono l'inizializzazione del contesto JNDI e la localizzazione dell'oggetto Factory [GOF] d'interesse.
Di seguito si riporta il codice di un client che ricerca un EJB mediante le API JNDI senza utilizzare il pattern Service Locator :
In questo caso l'implementazione del Service Locator è un Singleton [GOF] su cui si invoca un metodo (getHome) specificando come parametro di input (SERVICEID) il servizio da ricercare (algoritmo di tipo "type-checked"). L'implementazione del ServiceLocator proposta, espone anche API in cui è richiesto espressamente il nome del servizio e la classe che si sta ricercando. Un approccio di questo tipo è detto "type-unchecked".
A parità di funzionalità offerte, il client che utilizza il ServiceLocator non è chiamato ad effettuare le operazioni di lookup e di narrow; conseguentemente non deve importare i package java.rmi e javax.naming.
Struttura
Si riportano i diagrammi UML relativi al pattern.
Class Diagram (ServiceLocator EJBHome)Class Diagram (ServiceLocator TopicConnectionFactory)Sequence Diagram (EJB Home)Sequence Diagram (TopicConnectionFactory) (clicca sull'immagine per ingrandire)
Presentazione del codice Java
Viene ora presentato un esempio di implementazione.
Class Diagram dell'esempio proposto (clicca sull'immagine per ingrandire)
Come prima cosa bisogna definire gli ID logici dei servizi che verranno utilizzati dal client per indicare il servizio d'interesse.
public
final static int MOKA_SHOPPER_SERVICE = 0;
public final static int MOKA_ACCOUNT_SERVICE = 1;
. . .
Si deve provvedere a configurare opportunamente ogni servizio specificando la classe Home, la classe ContextFactory, il Provider URL ed il JNDI name. Per fare questo ci si avvale di una classe Helper il cui compito è di contenere i dati di configurazione del servizio mettendo a disposizione i relativi metodi accessor.
Il parametro service individua l'oggetto ServiceConfig da utilizzare al fine di localizzare il servizio d'interesse.
public
EJBHome getHome(int service) throws ServiceLocationException {
EJBHome home = null;
try {
// Look up using the service name from defined constant
ServiceConfig config =
(ServiceConfig)MyServiceLocator.businessServices[service];
Context ctx =
this.getInitialContext(config.getInitialContextFactory(),
config.getProviderUrl());
Object objref = ctx.lookup(config.getJndiName());
// Narrow using the EJBHome Class from defined constant
Object obj = PortableRemoteObject.narrow(
objref, config.getHomeClass());
home = (EJBHome)obj;
}
catch(Exception ex) {
ex.printStackTrace();
throw new ServiceLocationException(ex.getMessage());
}
return home;
}
Un caso d'uso
Il caso d'uso proposto prevede un programma client che richiede alla classe ServiceLocator di reperire :
l'EJB Account installato sull'Application Server SUN Reference Implementation [DAO] in modalità "type-checked" AccountHome home =(AccountHome)MyServiceLocator.getInstance().getHome( MyServiceLocator.MOKAACCOUNTSERVICE);
l'EJB Shopper installato sull'Application Server JBoss[FACADE] in modalità "type- checked" ShopperHome home = (ShopperHome)MyServiceLocator.getInstance().getHome( MyServiceLocator.MOKASHOPPERSERVICE);
l'EJB Facade installato sull'Application Server JBoss[FACADE] in modalità "type-unchecked" FacadeHome home = (FacadeHome)MyServiceLocator.getInstance().getHome( JndiNames.FACADE,FacadeHome.class);
il Topic Connection Factory [JMS] installato sull'Application Server JBoss in modalità "type-unchecked" TopicConnectionFactory home TopicConnectionFactory) MyServiceLocator.getInstance(). getTopicHome( JndiNames.TOPICCONNECTIONFACTORY);
MokaByte®
è un marchio registrato da MokaByte s.r.l.
Java®, Jini® e tutti i nomi derivati sono marchi
registrati da Sun Microsystems.
Tutti i diritti riservati. E' vietata la riproduzione
anche parziale.
Per comunicazioni inviare una mail a info@mokabyte.it