3. Escenarios de uso
3.2. Inicio de sesión
El inicio de sesión o loggin es una dependencia muy importante para Spring porque:
Es la única dependencia externa obligatoria.
A todo el mundo le gusta ver las salidas de las herramientas que están utilizando.
Spring se integra con otras herramientas que también tienen una dependencia de registro.
Uno de los objetivos que un desarrollador de aplicaciones suele tener es el de tener unificado el loggin en un lugar central para toda la aplicación, incluyendo todos los componentes externos. La dependencia del loggin obligatorio en Spring viene dada por la API Jakarta Commons Logging (JCL). Spring recompila JCL y también hace los objetos JCL Log visibles para todas las clases que extienden de Spring Framework. Uno de los aspectos más importantes para los usuarios es que todas las versiones de Spring utilizan la misma biblioteca de registro, esto facilita la migración debido a que la compatibilidad hacia atrás se conserva incluso con aplicaciones que extienden Spring. La forma de hacer que esto sea posible es permitiendo que uno de los módulos en Spring dependa explícitamente de commons-logging (la aplicación canónica de JCL) y, a continuación, hacer que todos los demás módulos dependan de el en tiempo de compilación.
Lo bueno de commons-logging es que el desarrollador no necesita nada más para desarrollar la aplicación. Cuenta con un algoritmo de descubrimiento de ejecución que busca otros
46
frameworks de registro situados en lugares bien conocidos de la ruta de clases para utilizar el que considere más apropiado, o el que se le indique.
No utilizar Commons Logging
Desafortunadamente, el algoritmo de descubrimiento de ejecución de commons-logging es problemático. Si se pudiera volver a empezar Spring como un nuevo proyecto usaría una dependencia de registro diferente. Probablemente la primera opción sería la fachada de registro de Java (SLF4J), que también es utilizada por una gran cantidad de herramientas que utilizan las personas con Spring dentro de sus aplicaciones.
Básicamente, hay dos formas para apagar commons-logging:
1. Excluir la dependencia del módulo Spring-core (ya que es el único módulo que depende explícitamente de commons-logging).
2. Crear una dependencia especial de commons-logging que sustituyera a la biblioteca con un .jar vacío.
Para excluir commons-logging, hay que añadir el siguiente fragmento de código a la sección DependencyManagement:
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.0.2.RELEASE</version>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency> </dependencies>
Ahora bien, esta aplicación probablemente estará “rota” ya que no existe ninguna implementación de la API de JCL en la ruta de clases, por lo que para arreglarlo es necesario proporcionar una nueva.
En las siguientes secciones se mostrará cómo proporcionar una implementación alternativa de JCL usando SLF4J y Log4J.
Usando SLF4J
SLF4J es una dependencia más limpia y eficiente en tiempo de ejecución que commons- logging, ya que utiliza enlaces en tiempo de compilación en lugar de descubrimientos en tiempo de ejecución de los otros frameworks de registro que se integran en la aplicación. Esto también significa que el desarrollador tiene que ser más explícito acerca de lo que quiere que ocurra en tiempo de ejecución, y por lo tanto declararlo o configurarlo en consecuencia. SLF4J proporciona enlaces a muchos frameworks de registro comunes, por lo que normalmente se
47
puede elegir uno que ya se esté utilizando, con lo que se conseguirá unificar la configuración y la administración.
SLF4J proporciona enlaces a muchos frameworks de registro comunes, incluyendo JCL, y también hace lo contrario, puentes entre otros frameworks de registro y el suyo.Así que para usar SLF4J con Spring es necesario sustituir la dependencia decommons-logging por un puente SLF4J-JCL.Una vez que haya hecho esto entonces el registro de llamadas desde el interior de Spring será traducido al registro de llamadas de la API SLF4J, así que si otras bibliotecas de la aplicación utilizan esa API, entonces se consigue tener solo un lugar para configurar y administrar el registro.
Una opción común es la de hacer un puente de Spring a SLF4J y, a continuación, proporcionar un enlace explícito de SLF4J a Log4J. Para ello se deberán proporcionar 4 dependencias (el puente, la API SLF4J, la unión a Log4J y la implementación Log4J en sí misma) y excluir commons-logging. En Maven habría que hacer algo como esto:
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.0.2.RELEASE</version>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>1.5.8</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.5.8</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.5.8</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.14</version>
</dependency> </dependencies>
Aunque pueda parecer que hay que especificar muchas dependencias es opcional, y proporciona un mejor comportamiento que el de commons-logging con respecto a las cuestiones de cargar las clases, sobre todo si se encuentra en un recipiente estricto como la
48
plataforma OSGi.Además proporciona mejoras en el rendimiento debido a que los enlaces se realizan en tiempo de compilación y no en tiempo de ejecución.
Una opción más común entre los usuarios SLF4J, que utilizan menos pasos y generan un menor número de dependencias, es vincularlo directamente a Logback. Esto elimina un paso de unión extra porque Logback implementa directamente SLF4J, por lo que sólo tendrá que depender de dos bibliotecas y no de cuatro (JCL-over-slf4j y logback). Si se hace esto es necesario también excluir la dependencia slf4j-api de las otras dependencias externas (no de la de Spring), porque sólo se necesita una versión de esa API en la ruta de clases.
Usando Log4J
Mucha gente utilizaLog4jcomo un framework de registro para fines de configuración y administración. Esto es eficaz y está bien establecido, y de hecho es lo que se suele usar a la hora de desarrollar y probar Spring.Spring también proporciona algunas herramientas para configurar e inicializar Log4j, por lo que tiene una dependencia en tiempo de compilación con Log4j en algunos módulos.
Para hacer el trabajo Log4j con commons-logging todo lo que se necesita hacer es poner Log4j en la ruta de clases y dotarla de un archivo de configuración (log4j.properties o log4j.xml en la raíz de la ruta de clases). Así que para los usuarios de Maven la declaración de dependencia debería ser:
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.0.2.RELEASE</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.14</version>
</dependency> </dependencies>
A continuación se muestra un ejemplo de log4j.properties para el registro mediante consola: log4j.rootCategory=INFO, stdout log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %t %c{2}:%L - %m%n log4j.category.org.springframework.beans.factory=DEBUG
49
Runtime Recipientes con JCL Nativo
Muchas personas ejecutan sus aplicaciones de Spring en un contenedor que a su vez proporciona una implementación de JCL. IBM Websphere Application Server (WAS) es el arquetipo. Esto a menudo causa problemas, y por desgracia no hay una solución mágica, simplemente excluyendo commons-logging de la aplicación no es suficiente en la mayoría de las situaciones.
Para ser claro, los problemas por lo general no están relacionados con JCL, o con commons- logging, sino que tienen que ver con la unión de commons-logging con otro framework (a menudo Log4J). Esto puede ocurrir debido a que commons-logging ha cambiado la forma de hacer el descubrimiento en tiempo de ejecución de cómo lo hacía en las versiones anteriores. Spring no utiliza partes inusuales del API de JCL, cosa que no causa ningún tipo de problema, pero tan pronto como Spring o la aplicación desarrollada traten de hacer cualquier registro se pueden encontrar con que los enlaces a Log4J no están funcionando.
En estos casos la cosa más fácil de hacer es invertir la jerarquía del cargador de clases para que la aplicación sea la que controle la dependencia JCL y no el contenedor. Esa opción no siempre es factible, pero hay muchas otras alternativas que pueden variar dependiendo de la versión exacta y el conjunto de características del contenedor.
51
53
En este capítulo se explicaran las múltiples opciones que Spring proporciona para construir una capa de persistencia. Spring es compatible con todos los frameworks de persistencia que existen para Java como pueden ser Hibernate, Java Persistence API (JPA), iBATIS, o cualquier otro.