Esta API tiene 2 distintos propositos/significados, ambos enfocadoes en desacoplar modulos
.- JDK 6 ServiceLoader Class. proveedores de servicios multiples cargados por la clase "LookUp"
via interface compartida.
.- Context Sensitivity. objetos Netbeans, e.g., windows, tienen un "lookup", definiendo capacidades, las cuales cambian dinamicamente.
Ejemplo:
pequeño ejemplo de uso JDK 6 service load
Este no usa los netbeans modules, se creará una simple aplicación java
File -> New Project -> Java -> Java Application
esta definirá un servicio que será expuesta a traves de un ServiceInterface
Crearemos otra simple aplicación java, donde pondremos la primer aplicación java dentro del classpath de la segunda aplicación java. La segunda aplicación java definirá el ServiceProvider
el cual implementa la interface (ServiceInterface). Esto es posible por que la primera aplicación java esta en el classpath de la segunda aplicación java. La segunda aplicación java expondrá el ServiceProvider a través del mecanismo JDK 6 ServiceLoader Class, por medio del paquete java META-INF.services, lo que es lo mismo un folder META-INF y subfolder services. el cual contiene un archivo con el nombre calificado del ServiceInterface. (org.demo.services.ServiceInterface como esta definida en la primer aplicación java). Este archivo contiene los nombres calificados de los ServiceProviders definidos en la segunda aplicación java. (org.demo.ServiceProvider1, org.demo.ServiceProvider2).
Posteriormente se crea una trecer aplicación java, que dependera de la primera y segunda aplicación (agregar a la librería), esta utilizará JDK ServiceLoader Class, para cargar los ServiceProviders a través de ServiceInterface. Esto es posible por que la segunda aplicación expone los servicios por medio del folder META-INF services.
Adicionalmente y no necesario para la simplicidad de este ejemplo, se crea una cuarta aplicación java que duplica a la segunda aplicación java, que en este caso define un ServiceProviderB1.
La estructura de estas sencillas aplicaciones java se muestra en NetBeans en la siguiente figura
El diagrama UML
La ejecución de la tercera aplicación 3AppServiceDisplayer llamara metodos de las otras aplicaciones por medio de la interface, gracias a las dependecias que el JDK 6 class loader puede resolver.
run:
Service Called:returns ServiceProvider1 from 2AppDemoService which implements ServiceInterface from 1AppDemoService
Service Called:returns ServiceProvider2 from 2AppDemoService which implements ServiceInterface from 1AppDemoService
Service Called:returns ServiceProviderB1 from 4AppDemoService which implements ServiceInterface from 1AppDemoService
BUILD SUCCESSFUL (total time: 0 seconds)
El código en github
https://github.com/jalbertomr/simpleLookupAPI.git
Otra Forma de llegar al mismo objetivo es usar la plataforma de Netbeans Modules, los cuales se comunicarán entre ellos, así se ayuda a tener un código más organizado. Esto se logra
creando un projecto NetBeans Platform Applications
File -> New Project -> NetBeans Modules -> NetBeans Platform Applications
name: AppSimpleNetBeansModule
Se ajustan las librerias a incluir a lo básico:
Project Window -> click derecho en AppSimpleNetBeansModule -> Properties -> Libraries -> platform
Se eligen solamente los paquetes básicos esto es bootstrap, Startup, Module System, File System, Utilities adicionalmente sugerirá netbeans resolver agregar más paquetes por dependencia a lo que asentiremos positivamente.
Se agrega un nuevo modulo a la aplicación creada:
AppSimpleNetBeansModule -> Modules -> click derecho -> add new...
project name: ModuleAppSimple
Le agregamos una Module Installer
ModuleAppSimple -> new.. -> Module Installer
Al método restored() que se generó, simplemente le agregamos un println("Hello world");
y ejecutamos la aplicación AppSimpleNetBeansModule
-------------------------------------------------------------------------------
Hello World!
INFO [org.netbeans.core.startup.NbEvents]: Turning on modules:
org.openide.util.lookup [8.33.1 201609300101]
org.openide.util [9.7.1 201609300101]
org.openide.util.ui [9.6.1 201609300101]
org.openide.modules [7.48.1 201609300101]
org.openide.filesystems [9.10.1 201609300101]
org.openide.filesystems.compat8 [9.9.1 201609300101]
org.netbeans.libs.asm [5.3.1 201609300101]
org.netbeans.demo [1.0 170926]
org.netbeans.core.startup.base [1.62.1.1 1 201609300101]
org.netbeans.bootstrap/1 [2.76.1 201609300101]
org.netbeans.core.startup/1 [1.62.1.1 201609300101]
BUILD SUCCESSFUL (total time: 31 seconds)
Indica como módulos pueden comunicarse con otros en una forma desacoplada.
Realizando la misma tarea que se hizo en el ejemplo que utiliza JDK 6 Class loader, pero con la plataforma NetBeans Modules, tenemos una estructura como esta
Project Properties -> API Versioning -> Public packages se hacen publicos los paquetes para que tengan visibilidad por los módulos que los utilizarán, y en los módulos que los utilizarán o haran referencia a ellos, se los agregarán en su librería.
Ejecutando tenemos:
-------------------------------------------------------------------------------
Windows Restored...
Service Called: ServicePrivider1 from DemoServiceProviderB which implements ServiceInterface from DemoService
Service Called: ServiceProvider1 from DemoServiceProviderA which implements ServiceInterface from DemoService
Service Called: ServiceProvider2 from DemoServiceProviderA which implements ServiceInterface from DemoService
INFO [org.netbeans.core.startup.NbEvents]: Turning on modules:
org.openide.util.lookup [8.33.1 201609300101]
org.openide.util [9.7.1 201609300101]
org.openide.util.ui [9.6.1 201609300101]
org.openide.modules [7.48.1 201609300101]
org.openide.filesystems [9.10.1 201609300101]
org.openide.filesystems.compat8 [9.9.1 201609300101]
org.netbeans.libs.asm [5.3.1 201609300101]
org.netbeans.core.startup.base [1.62.1.1 1 201609300101]
org.netbeans.bootstrap/1 [2.76.1 201609300101]
org.netbeans.core.startup/1 [1.62.1.1 201609300101]
org.demo.service [1.0 170610]
org.demo.serviceProviderB [1.0 170610]
org.demo.serviceProvider [1.0 170610]
org.demo.consumer [1.0 170926]
BUILD SUCCESSFUL (total time: 26 seconds)
El LookupAPI puede hacer más, No solamente es un service loader, en primera instancia tiene un listener el cual detecta cuando hay un nuevo service provider cargado por el runtime container. Esto permite integrar un módulo dinámicamente a una aplicación en runtime.
en segundo lugar se puede implementar context sensitivity
No hay comentarios:
Publicar un comentario