Creación de frijoles de primavera a través de métodos de fábrica

1. Introducción

Los métodos de fábrica pueden ser una técnica útil para ocultar la lógica de creación compleja dentro de una sola llamada a un método.

Si bien comúnmente creamos beans en Spring usando constructor o inyección de campo, también podemos crear Spring beans usando métodos de fábrica .

En este tutorial, profundizaremos en la creación de Spring beans utilizando métodos de fábrica estáticos y de instancia.

2. Método de fábrica de instancias

Una implementación estándar del patrón del método de fábrica es crear un método de instancia que devuelva el bean deseado.

Además, podemos configurar Spring para crear nuestro bean deseado con o sin argumentos .

2.1. Sin argumentos

Podemos crear una clase Foo que represente la creación de nuestro bean:

public class Foo {}

Luego, creamos una clase InstanceFooFactory que incluye un método de fábrica, createInstance , que crea nuestro bean Foo :

public class InstanceFooFactory { public Foo createInstance() { return new Foo(); } }

Después de eso, configuramos Spring:

  1. Cree un bean para nuestra clase de fábrica ( InstanceFooFactory )
  2. Utilice el atributo factory-bean para hacer referencia a nuestro factory bean
  3. Utilice el atributo de método de fábrica para hacer referencia a nuestro método de fábrica ( createInstance )

Aplicando esto a una configuración Spring XML, terminamos con:

Por último, conectamos automáticamente nuestro bean Foo deseado . Spring luego creará nuestro bean usando nuestro método de fábrica createInstance :

@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration("/factorymethod/instance-config.xml") public class InstanceFooFactoryIntegrationTest { @Autowired private Foo foo; @Test public void givenValidInstanceFactoryConfig_whenCreateFooInstance_thenInstanceIsNotNull() { assertNotNull(foo); } }

2.2. Con argumentos

También podemos proporcionar argumentos a nuestro método de fábrica de instancias usando el elemento constructor-arg en nuestra configuración de Spring.

Primero, creamos una clase, Bar , que utiliza un argumento:

public class Bar { private String name; public Bar(String name) { this.name = name; } // ...getters & setters }

A continuación, creamos una clase de fábrica de instancias, InstanceBarFactory , con un método de fábrica que acepta un argumento y devuelve un bean Bar :

public class InstanceBarFactory { public Bar createInstance(String name) { return new Bar(name); } }

Por último, agregamos un elemento constructor-arg a nuestra definición de bean Bar :

Luego, podemos conectar automáticamente nuestro bean Bar de la misma manera que lo hicimos con nuestro bean Foo :

@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration("/factorymethod/instance-bar-config.xml") public class InstanceBarFactoryIntegrationTest { @Autowired private Bar instance; @Test public void givenValidInstanceFactoryConfig_whenCreateInstance_thenNameIsCorrect() { assertNotNull(instance); assertEquals("someName", instance.getName()); } }

3. Método de fábrica estático

También podemos configurar Spring para usar un método estático como método de fábrica.

Si bien se deben preferir los métodos de fábrica de instancias, esta técnica puede ser útil si tenemos métodos estáticos heredados que producen los beans deseados. Por ejemplo, si un método de fábrica devuelve un singleton, podemos configurar Spring para usar este método de fábrica de singleton.

De manera similar a los métodos de fábrica de instancias, podemos configurar métodos estáticos con y sin argumentos.

3.1. Sin argumentos

Usando nuestra clase Foo como nuestro bean deseado, podemos crear una clase, SingletonFooFactory , que incluye un método de fábrica createInstance que devuelve una instancia singleton de Foo :

public class SingletonFooFactory { private static final Foo INSTANCE = new Foo(); public static Foo createInstance() { return INSTANCE; } }

Esta vez, solo necesitamos crear un bean. Este bean requiere solo dos atributos:

  1. class - declara nuestra clase de fábrica ( SingletonFooFactory )
  2. método de fábrica : declara el método de fábrica estático ( createInstance )

Aplicando esto a nuestra configuración Spring XML, obtenemos:

Por último, conectamos automáticamente nuestro bean Foo usando la misma estructura que antes:

@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration("/factorymethod/static-foo-config.xml") public class SingletonFooFactoryIntegrationTest { @Autowired private Foo singleton; @Test public void givenValidStaticFactoryConfig_whenCreateInstance_thenInstanceIsNotNull() { assertNotNull(singleton); } }

3.2. Con argumentos

Si bien debemos evitar cambiar el estado de los objetos estáticos, como nuestro singleton, cuando sea posible , aún podemos pasar argumentos a nuestro método de fábrica estática.

Para hacer esto, creamos un nuevo método de fábrica que acepta nuestros argumentos deseados:

public class SingletonBarFactory { private static final Bar INSTANCE = new Bar("unnamed"); public static Bar createInstance(String name) { INSTANCE.setName(name); return INSTANCE; } }

Después de eso, configuramos Spring para pasar el argumento deseado usando el elemento constructor-arg :

Por último, conectamos automáticamente nuestro bean Bar usando la misma estructura que antes:

@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration("/factorymethod/static-bar-config.xml") public class SingletonBarFactoryIntegrationTest { @Autowired private Bar instance; @Test public void givenValidStaticFactoryConfig_whenCreateInstance_thenNameIsCorrect() { assertNotNull(instance); assertEquals("someName", instance.getName()); } }

4. Conclusión

En este artículo, analizamos cómo configurar Spring para usar la instancia y los métodos de fábrica estáticos, con y sin argumentos.

Si bien la creación de beans mediante inyección de campo y constructor es más común, los métodos de fábrica pueden ser útiles para pasos de creación complejos y código heredado.

El código utilizado en este artículo se puede encontrar en GitHub.