Creazione di fagioli primaverili attraverso metodi di fabbrica

1. Introduzione

I metodi factory possono essere una tecnica utile per nascondere la logica di creazione complessa all'interno di una singola chiamata al metodo.

Sebbene creiamo comunemente bean in Spring utilizzando il costruttore o l'iniezione di campo, possiamo anche creare bean Spring utilizzando i metodi di fabbrica .

In questo tutorial, approfondiremo la creazione di bean Spring utilizzando sia i metodi di istanza che quelli di fabbrica statici.

2. Metodo Instance Factory

Un'implementazione standard del pattern del metodo factory consiste nel creare un metodo di istanza che restituisca il bean desiderato.

Inoltre, possiamo configurare Spring per creare il nostro bean desiderato con o senza argomenti .

2.1. Senza argomenti

Possiamo creare una classe Foo che rappresenta il nostro bean in fase di creazione:

public class Foo {}

Quindi, creiamo una classe InstanceFooFactory che include un metodo factory, createInstance , che crea il nostro Foo bean:

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

Successivamente, configuriamo Spring:

  1. Crea un bean per la nostra classe factory ( InstanceFooFactory )
  2. Utilizza l' attributo factory-bean per fare riferimento al nostro bean di fabbrica
  3. Usa l' attributo factory-method per fare riferimento al nostro metodo factory ( createInstance )

Applicando questo a una configurazione Spring XML, si ottiene:

Infine, autowire il nostro Foo bean desiderato . Spring creerà quindi il nostro bean utilizzando il nostro metodo di fabbrica 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 argomenti

Possiamo anche fornire argomenti al nostro metodo factory di istanze usando l' elemento constructor-arg nella nostra configurazione Spring.

Innanzitutto, creiamo una classe, Bar , che utilizza un argomento:

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

Successivamente, creiamo una classe factory di istanze, InstanceBarFactory , con un metodo factory che accetta un argomento e restituisce un bean Bar :

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

Infine, aggiungiamo un elemento costruttore-arg alla nostra definizione di Bar bean:

Possiamo quindi autowire il nostro Bar bean nello stesso modo in cui abbiamo fatto per il nostro Foo bean:

@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. Metodo di fabbrica statico

Possiamo anche configurare Spring per utilizzare un metodo statico come metodo di fabbrica.

Sebbene i metodi di fabbrica di istanze dovrebbero essere preferiti, questa tecnica può essere utile se disponiamo di metodi statici esistenti e legacy che producono i bean desiderati. Ad esempio, se un metodo factory restituisce un singleton, possiamo configurare Spring per utilizzare questo metodo factory singleton.

In modo simile ai metodi factory di istanza, possiamo configurare metodi statici con e senza argomenti.

3.1. Senza argomenti

Usando la nostra classe Foo come bean desiderato, possiamo creare una classe, SingletonFooFactory , che include un metodo factory createInstance che restituisce un'istanza singleton di Foo :

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

Questa volta, dobbiamo creare solo un fagiolo. Questo bean richiede solo due attributi:

  1. class - dichiara la nostra classe di fabbrica ( SingletonFooFactory )
  2. factory-method - dichiara il metodo factory statico ( createInstance )

Applicando questo alla nostra configurazione Spring XML, otteniamo:

Infine, autowire il nostro Foo bean usando la stessa struttura di prima:

@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 argomenti

Sebbene dovremmo evitare di cambiare lo stato degli oggetti statici, come il nostro singleton, quando possibile , possiamo comunque passare argomenti al nostro metodo factory statico.

Per fare ciò, creiamo un nuovo metodo factory che accetta i nostri argomenti desiderati:

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

Dopodiché, configuriamo Spring per passare l'argomento desiderato utilizzando l' elemento constructor-arg :

Infine, autowire il nostro Bar bean utilizzando la stessa struttura di prima:

@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. Conclusione

In questo articolo, abbiamo esaminato come configurare Spring per utilizzare metodi di istanza e factory statici, sia con che senza argomenti.

Sebbene la creazione di bean tramite il costruttore e l'inserimento di campi sia più comune, i metodi factory possono essere utili per passaggi di creazione complessi e codice legacy.

Il codice utilizzato in questo articolo può essere trovato su GitHub.