Erstellen von Frühlingsbohnen mit Factory-Methoden

1. Einleitung

Factory-Methoden können eine nützliche Technik sein, um komplexe Erstellungslogik in einem einzigen Methodenaufruf zu verbergen.

Während wir im Frühjahr normalerweise Beans mit Konstruktor- oder Feldinjektion erstellen, können wir Spring Beans auch mit Factory-Methoden erstellen .

In diesem Tutorial werden wir uns mit dem Erstellen von Spring Beans sowohl mit Instanz- als auch mit statischen Factory-Methoden befassen.

2. Instance Factory-Methode

Eine Standardimplementierung des Factory-Methodenmusters besteht darin, eine Instanzmethode zu erstellen, die die gewünschte Bean zurückgibt.

Darüber hinaus können wir Spring so konfigurieren, dass die gewünschte Bean mit oder ohne Argumente erstellt wird .

2.1. Ohne Argumente

Wir können eine Foo- Klasse erstellen , die unsere zu erstellende Bohne darstellt:

public class Foo {}

Anschließend erstellen wir eine InstanceFooFactory- Klasse, die die Factory-Methode createInstance enthält , mit der unsere Foo- Bean erstellt wird:

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

Danach konfigurieren wir Spring:

  1. Erstellen Sie eine Bean für unsere Factory-Klasse ( InstanceFooFactory )
  2. Verwenden Sie das Factory-Bean- Attribut, um auf unsere Factory -Bean zu verweisen
  3. Verwenden Sie das Attribut factory-method , um auf unsere Factory-Methode ( createInstance ) zu verweisen.

Wenn wir dies auf eine Spring XML-Konfiguration anwenden, erhalten wir Folgendes:

Zuletzt verdrahten wir unsere gewünschte Foo- Bohne automatisch . Spring erstellt dann unsere Bean mit unserer Factory-Methode 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. Mit Argumenten

Wir können unserer Instanzfactory-Methode auch Argumente bereitstellen, indem wir das Konstruktor- Argument - Element in unserer Spring-Konfiguration verwenden.

Zuerst erstellen wir eine Klasse, Bar , die ein Argument verwendet:

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

Als Nächstes erstellen wir eine Instanzfactory-Klasse, InstanceBarFactory , mit einer Factory-Methode, die ein Argument akzeptiert und eine Bar- Bean zurückgibt :

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

Zuletzt fügen wir unserer Bar- Bean-Definition ein Konstruktor-Argument- Element hinzu :

Wir können dann unsere Bar Bean auf die gleiche Weise automatisch verdrahten wie für unsere 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. Statische Factory-Methode

Wir können Spring auch so konfigurieren, dass eine statische Methode als Factory-Methode verwendet wird.

Während Instanz-Factory-Methoden bevorzugt werden sollten, kann diese Technik nützlich sein, wenn vorhandene, ältere statische Methoden vorhanden sind, die die gewünschten Beans erzeugen. Wenn eine Factory-Methode beispielsweise einen Singleton zurückgibt, können wir Spring so konfigurieren, dass diese Singleton-Factory-Methode verwendet wird.

Ähnlich wie bei Instance Factory-Methoden können wir statische Methoden mit und ohne Argumente konfigurieren.

3.1. Ohne Argumente

Mit unserer Foo- Klasse als gewünschte Bean können wir eine Klasse, SingletonFooFactory , erstellen , die eine createInstance- Factory-Methode enthält, die eine Singleton-Instanz von Foo zurückgibt :

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

Dieses Mal müssen wir nur eine Bohne erstellen. Diese Bean benötigt nur zwei Attribute:

  1. Klasse - deklariert unsere Factory-Klasse ( SingletonFooFactory )
  2. Factory-Methode - deklariert die statische Factory-Methode ( createInstance )

Wenn wir dies auf unsere Spring XML-Konfiguration anwenden, erhalten wir:

Zuletzt verdrahten wir unsere Foo- Bohne automatisch mit der gleichen Struktur wie zuvor:

@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. Mit Argumenten

Obwohl wir nach Möglichkeit vermeiden sollten, den Status statischer Objekte wie unseres Singletons zu ändern , können wir dennoch Argumente an unsere statische Factory-Methode übergeben.

Dazu erstellen wir eine neue Factory-Methode, die unsere gewünschten Argumente akzeptiert:

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

Danach konfigurieren wir Spring so, dass das gewünschte Argument mit dem Konstruktor- Argument - Element übergeben wird:

Zuletzt verdrahten wir unsere Bar Bean automatisch mit der gleichen Struktur wie zuvor:

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

In diesem Artikel haben wir uns mit der Konfiguration von Spring für die Verwendung von Instanz- und statischen Factory-Methoden befasst - sowohl mit als auch ohne Argumente.

Während das Erstellen von Beans durch Konstruktor- und Feldinjektion häufiger vorkommt, können Factory-Methoden für komplexe Erstellungsschritte und Legacy-Code hilfreich sein.

Der in diesem Artikel verwendete Code ist auf GitHub zu finden.