Tenéis que estar orgullosos de vuestro enemigo
F. Nietzsche

Spring 3 – Inyección de Dependencias – Anotaciones

Una manera muy cómoda de inyectar las dependencias a una clase en Spring 3 es mediante el uso de etiquetas. De momento, yo sólo uso esta modalidad para inyectar las dependencias en los test: si quiero probar un DAO prefiero utilizar una anotación a tener que crear un XML porque seguramente será poco reutilizable.

En Spring v03.xx tenemos las siguientes posibilidades de popular beans mediante etiquetas:

@Resource, es una etiqueta especificada en la Java Specefication Request JSR-250 (Common Annotations for the JavaTM Platform). En Spring, inyectará la dependencia por nombre. Es decir, buscará dentro del contexto un bean cuyo nombre coincida con el nombre de la variable etiquetada. En el Contenedor IoC, un bean puede tener uno o más identificadores (puede tener aliases), pero todos ellos deben ser únicos en el ámbito del contenedor.

@Autowired, es una etiqueta especificada por el propio framework de Spring. En Spring, inyectará la dependencia por tipo. Es decir, buscará dentro del contexto un bean cuya clase coincida con el tipo de variable etiquetada.

@Inject, es una etiqueta especificada en la Java Specefication Request JSR-330 (Dependency Injection for Java). Es intercambiable por la etiqueta @Autowired siempre que su JAR esté en nuestro classpath.

La inyección de dependencias por tipo puede encontrarse con que dentro del mismo contexto existan más de un bean con el mismo tipo. Un ejemplo sería si tenemos un bean llamado administrador del tipo persona, otro bean llamado superadministrador del tipo persona, y una variable de tipo persona etiquetada con @Autowired o @Inject. Estos casos se utiliza la etiqueta @Qualifier para discriminar por nombre el bean que deseamos cargar, ya que el nombre sí que es único dentro del contenedor.

Ojo, porque la implementación de la etiqueta @Qualifier de la JSR-330 es distinta a la de la etiqueta @Qualifier de Spring v03.xx.

En resumen

¿Cuál es la mejor forma de inyectar dependencias en Spring 3? ¿Mediante configuración XML, mediante código Java, mediante anotaciones de Spring o mediante anotaciones de JSR-330? Pues la respuesta, como casi siempre en este tipo de preguntas, es que depende de la situación :)

Relacionado

@Required, esta etiqueta simplemente indica que la propiedad anotada debe ser populada en tiempo de configuración, es decir cuando se carga el contexto de Spring, bien mediante Autowiring o bien mediante configuración del bean en el XML. Si no es populada, entonces Spring lanza una excepción.

Notas

Ver la documentación original de Spring 3:

En versiones anteriores a v03.xx no existe diferencias entre las etiquetas.

Code Kata – Integración GWT, Maven y Spring Framework

Esta kata es una continuación de la anterior kata sobre GWT. El objetivo es conseguir gestionar el proyecto con Maven para poder utilizar GWT simplemente como framework de vista en nuestros proyectos profesionales, y conseguir gestionar las dependencias entre beans utilizando Spring Framework.

El mayor problema que nos encontraremos con Maven es que la “filosofía” de GWT es muy antigua, Java de finales de los años 90 con notables deficiencias desde un punto de vista actual de desarrollo de software aún en las versiones más recientes (como mezclar código fuente con código generado), en las que los proyectos son GWT o no en lugar de utilizar GWT como un simple framework más que simplemente se utiliza en la vista y el control.

El mayor problema que nos encontraremos en Spring Framework es que GWT crea las instancias de las RPCs asíncronas, que a su vez utilizan componentes creados por Spring (los servicios) y gestionados en su contexto. Ojo, no confundir Spring Framework para gestionar dependencias con Spring MVC para gestionar la capa de control: utilizar Spring MVC para gestionar la capa de control no es el objetivo de esta kata aunque bien podría dar para otra kata diferente y luego compararla con la solución de esta kata.

Para esta kata se propone un orden concreto, primero convertir el proyecto GWT en proyecto Maven y luego introducir Spring, pero bien se podría realizar otra kata más al revés: primero introducir Spring en el proyecto GWT y luego convertirlo a un proyecto Maven. El resultado final debería ser el msimo.

Las versiones recomendadas para la realización de la kata son GWT v2.4, Maven v2.1 y Spring Framework v2.5. Las versiones antiguas de Maven y Spring Framework se deben a necesidades del proyecto para el que necesitaba aprender/enseñar, no creo que haya mayores diferencias con las respectivas versiones v03.xx.

Igual que en la anterior kata, no dudes en contactarme si tienes dudas, sugerencias o mejoras, publicaré mi solución pero te recomiendo encarecidamente que primero resuelvas la kata y luego la consultes, y agradeceré si decides compartir tu solución con nosotros.

Antes de consultar la solución propuesta (archivos war, sorry), te recomiendo encarecidamente que primero resuelvas la kata, aunque te cueste, aunque te atasques. El 1% que me hagáis caso vais a ser los que más provecho sacaréis de estas katas. Los que compartáis vuestras soluciones, mil gracias de antemano.

Algún día lo subiré a google code…

Ejercicio 01 – Integración Maven con GWT

Objetivos

  • Conseguir que cualquier ejercicio de la kata de GWT (preferiblemente el último) funcione bajo Maven.

Restricciones

  • La configuración del proyecto debe ser gestionado por Maven.
    • Las dependencias del proyecto (librerías) se deben gestionar con Maven.
    • El ciclo de vida del proyecto se debe controlar con Maven: limpiar, compilar, ejecutar, depurar y empaquetar.

Solución propuesta

Ejercicio 02 – Integración Spring con Maven con GWT

Objetivos

  • Partiendo del anterior proyecto, utilizar Spring para inyectar las dependencias.

Restricciones

  • Las mismas que en el ejercicio anterior.

Solución propuesta

How-to Migrate from Spring Framework to Guice

Iteration 0 – Stable Spring Application

We start from a Spring application that is stable, all automated tests are running and has been tested by ourselves. Assume we are using Spring Test Framework.

Let’s learn to walk before learning to run. Assume that we are the only developers on the project, and that it’s a little application.

If you don’t have any Java application for following this how-to tutorial, why don’t you implement an easy code kata? For example this one : Prime Factors (you can see UncleBob’s implementation following the link).

Someday I’ll give you the code of this how-to tutorial using a slyly modified version of this kata (warning, I’m a JEE-heavy-Spring style lover).

Iteration 1 – from Spring Test Framework to JUnit Framework

Our first step is changing our Testing Framework, unplugging the Spring Test Framework and replacing it for JUnit.

Remove Spring Test dependency from pom.xml (or remove the library from your class path). Test classes must extend junit.framework.TestCase. Test methods names must begin with “test” prefix (“primeNumberTest” is not a valid test method name, use “testPrimeNumber” instead).

Using JUnit for running test implies Spring no longer injects automatically required beans. We can choose to either use manually Spring API for create our Context and getting beans from it or use no ID at all. Let’s chose the second option to illustrate how an application works with 3 different injection’s mechanism (java old style, Guice style and Spring style).

All testing running? All green? Let´s continue.

Iteration 2: Dependency Injection: from Spring Framework to Guice Framework

Create Java classes for your Binding Modules (no need to say, into a new package for them). Remove your now useless XML Spring configuration files.

@Override

protected void configure() {

bind(RomanNumberBO.class).to(RomanNumberBOImpl.class);

bind(RomanNumbersValidation.class).to(RomanNumbersValidationImpl.class);

}

For each property, use Guice injector initialization them. You may now consider removing Setters of this properties, those which only purpose were being invocated by Spring in order to inject the dependency.

private RomanNumberBO romanNumberBO = Guice.createInjector(new RomanNumberModule()).getInstance(RomanNumberBO.class);

Test again. All right? All green? Then we’re done.

Migrating larger applications shared with more developers

Looks pretty easy, don’t you think? Migrating small applications where we are the only developers are easy. Big shared applications are not so easy to refactor, so don’t underestimated the task.

First step should be communicating the plan to all the members of your team, and close the details of the plan with them.

Second, all members who will participate in the migration process should complete a small migration process like the described above, or participate in “pair” programming session where one “expert” migrate one little module while the other are watching. If you prefer, a good document explain it could work too. My recommendation, both of them: first write the document, share it, be sure it’s read, and “pair” programming session.

The best strategy probably is starting from a 100% vs 0% modules used by old technology vs new technology, and as both technologies live together, begin migrate one by one modules from the littler and less critical until we reach the desired 0% vs 100%.

Continue with both technologies for a while (a few production deliveries) and when you feel comfortable, unplug all the remains of the old technology.

Java Dependency Injection: Guice or Spring?

Depending on your needs. Comparing both of them is like comparing a MP3 mobile player to an MP3 radio car. Spring provides you more and more powerful features and not only Dependency Injection (D.I.) : the MP3 radio car let you drive as you listen to your favorite music, but it’s harder to use if you want to spinning.

Google GuiceAlso, as you can use an MP3 mobile player in a car while a friend is driving, you can use Guice as D.I. Framework while Spring Framework is dealing with another stuffs.

Features

Guice is just a D.I. Framework, nothing more (but nothing less), so it’s quite light.

Spring gives you D.I. as part of its more featured (and heavy) core, but many other features are available that you can easily plug in (MVC, Testing, Security, Web Services Integration…). Also it’s easy to integrate with other Frameworks like Struts2 or Hibernate.

Configuration

Guice use no XML configuration files, but Java Modules classes instead where you define which bean implementation Guice will return when each Module is used. Also Annotations are supported.

Spring use XML configuration files for the same purpose using Java Beans name as identifiers, keeping Java language only for implementing your application features. Recently I’ve discovered @Autowired Annotation’s true power, keeping your XML configuration files much lighters. Also Annotations are supported.

Bean Injection

Using Guice, you must initialize using Guice injectors or Guice Annotations instead using constructors (“new”).

Spring not only automate beans dependencies injection, but also automate your beans creation process, so you will not need to use constructors: just implement all your attributes with private scope and generate public getters and setters methods and Spring will do all the work for you.  This solution is more elegant and less coupled. You can also use Annotations.

Testing

The only difference is that Spring Framework provides you  their own optional Testing Framework based on JUnit.

And finally, your champion is…?

Demo de Spring Security 3.0

Charla en InfoQ de Mike Wiesner (Senior Consultant de Spring) que nos introduce a Spring Security 3.0 mediante una demo.

Spring Security se puede utilizar en cualquier aplicación Java: no es necesario utilizar junto con el Framework de Spring completo (sino debe usarse AspectJ).

  • Da funcionalidades para cubrir la Autenticación y Autorización de tu aplicación.
  • Puede integrarse con JDBC, LDAP, JAAS, Kerberos…
  • Soporta integración entre distintos sistemas (para mapear permisos/roles de un sistema a permisos/roles de otro).
  • Soporta ACLs.
  • Permite implementar un Single Sign On (al soportar Kerberos que es el sistema de autenticación de Windows podemos implementar un SSO con el LDAP de la organización incluyendo mail, windows y demás apps).
  • Es posible configurarlo  con un xml y etiquetas en las clases Java (o centralizar la gestión de toda la aplicación en una única clase).

La configuración es muy simple siguiendo la misma filosofía que con el resto del Framework de Spring, creando un nuevo fichero xml de contexto.

Es posible utilizar el API de Spring Security a lo largo de nuestra aplicación, pero no es recomendable por razones de desacoplo y calidad:

  • se debería implementar un servicio (por ejemplo UserContextService) que haga de puente entre la API y la aplicación.
  • únicamente se testearía un servicio para toda las funcionalidades de Autenticación y Autorización.

La charla es interesante pero no he podido revisarla ni tampoco revisar estas anotaciones, que publico con un día de retraso.

Comenta