Ejemplo práctico de ServiceLoader con ServiceProvider de Java Money

Publicado por pico.dev el .
blog-stack java planeta-codigo programacion
Comentarios

Una aplicación que trabaje con importes y diferentes divisas necesitará ratios de conversión, estos ratios de conversión deberemos obtenerlos de algún servicio. Con la API de Java Money que aun en Java 8 no está incorporada en el JDK aunque si como una librería podremos trabajar de forma cómoda con importes, divisas y ratios. En este artículo explicaré un ejemplo de uso práctico de la clase ServiceLoader y como obtener ratios del servicio Open Exchange Rates.

Java

La semana pasada comentaba la clase ServiceLoader disponibles en el JDK y como nos puede servir para que nuestra aplicación o API sea extensible en futuras versiones o para alguien que quiera adaptarla a sus necesidades. La clase ServiceLoader es el método que se emplea en la API de Java para tratamiento de divisas, importes y conversiones que quizá en un futuro se ofrezca en Java con la especificación JSR-354. Por el momento se puede usar la librería con la implementación de referencia. En este ejemplo mostraré cómo proporcionar un nuevo proveedor de ratios que obtenga ratios de conversión del servicio Open Exchange Rates.

Para disponer del proveedor de ratios usable para Java Money deberemos implementar una clase que extienda de AbstractRateProvider junto con la implementación para el método getExchangeRate que devolverá los ratios, también el método newDataLoaded que procesará los datos de ratios obtenidos del servicio. El código del método getExchangeRate es una copia del proveedor del Banco Central Europeo (ECB), el método newDataLoaded obtiene los ratios a partir de un InputStream con los ratios devueltos por la URL del servicio, en el caso de Open Exchange Rates en el endpoint _/api/latest.json?app_id=[apikey].

Internamente la implementación de referencia de Java Money usa la clase ServiceLoader. En el archivo META-INF/services/javax.money.convert.ExchangeRateProvider incluimos el nombre cualificado completo de la clase de la implementación de AbstractRateProvider, en este caso io.github.picodotdev.javamoney.OpenExchangeRatesRateProvider.

También deberemos sobreescribir la propiedad conversion.default-chain en el archivo javamoney.properties, junto con algunas otras propiedades necesarias para que cargue los datos a partir de una URL del servicio que proporciona los ratios. La URL será la del servicio Open Exchange Rates que devolverá un resultado en formato JSON, lo procesaremos y construiremos los ExchangeRates a partir de los datos que nos son proporcionados en la clase AbstractRateProvider con el método newDataLoaded en forma de InputStream. En el archivo javamoney.properties el número entre llaves ({}) indica la prioridad de la propiedad cuando haya varios archivos javamoney.properties en diferentes archivos jar, deberemos indicar 0 o más ya que la prioridad por defecto es -1.

Implementado el servicio de ratios personalizado de Open Exhcnage Rates y configurado podemos usarlo con las siguientes líneas de código tal y como hacíamos con el servicio del Banco Central Europeo (ECB) proporcionado en la implementación de referencia de la librería de Java Money.

La API de Java Money ofrece más posibilidades como obtener datos históricos de los ratios de conversión, Open Exchange Rates también ofrece datos históricos en un endpoint tal que /api/historical/2011-10-18.json. Sin embargo, cómo hacer esto será tarea para el lector o tema para otro futuro artículo.

No es muy complicado lo que hay que hacer para integrar un proveedor de ratios sabiendo lo que hay que hacer y adaptando otro proveedor similar, sin embargo, no hay documentación que lo explique y he tenido que indagar en el código fuente del proyecto para saber cómo hacerlo, sin el código fuente me hubiese sido imposible escribir este artículo, esta es una de las ventajas del código abierto y software libre.

Puedes obtener el código fuente completo del ejemplo del repositorio de ejemplos de este blog en GitHub.