Lentebonen maken door middel van fabrieksmethoden

1. Inleiding

Fabrieksmethoden kunnen een nuttige techniek zijn om complexe aanmaaklogica te verbergen binnen een enkele methodeaanroep.

Hoewel we in het voorjaar vaak bonen maken met behulp van constructor of veldinjectie, we kunnen ook voorjaarsbonen maken met behulp van fabrieksmethoden.

In deze zelfstudie gaan we dieper in op het maken van Spring Beans met behulp van zowel instantiemethoden als statische fabrieksmethoden.

2. Instance Factory-methode

Een standaardimplementatie van het fabrieksmethode-patroon is om een ​​instantiemethode te maken die de gewenste bean retourneert.

Bovendien, we kunnen Spring configureren om onze gewenste boon met of zonder argumenten te creëren.

2.1. Zonder argumenten

We kunnen een Foo klasse die vertegenwoordigt onze boon die wordt gemaakt:

openbare les Foo {}

Vervolgens maken we een InstanceFooFactory klasse die een fabrieksmethode bevat, createInstance, dat creëert onze Foo Boon:

openbare klasse InstanceFooFactory {openbare Foo createInstance () {retourneer nieuwe Foo (); }}

Daarna configureren we Spring:

  1. Maak een boon voor onze fabrieksklasse (InstanceFooFactory)
  2. Gebruik de fabrieksboon attribuut om naar onze fabrieksboon te verwijzen
  3. Gebruik de fabrieksmethode attribuut om te verwijzen naar onze fabrieksmethode (createInstance)

Als we dit toepassen op een Spring XML-configuratie, krijgen we:

Ten slotte, we autowire onze gewenste Foo Boon. De lente zal dan onze boon maken met behulp van onze createInstance fabrieks methode:

@RunWith (SpringJUnit4ClassRunner.class) @ContextConfiguration ("/ factorymethod / instance-config.xml") openbare klasse InstanceFooFactoryIntegrationTest {@Autowired private Foo foo; @Test openbare ongeldig gegevenValidInstanceFactoryConfig_whenCreateFooInstance_thenInstanceIsNotNull () {assertNotNull (foo); }}

2.2. Met argumenten

We kunnen ook argumenten leveren voor onze instance factory-methode met behulp van de constructor-arg element in onze Spring-configuratie.

Eerst maken we een klas, Bar, dat een argument gebruikt:

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

Vervolgens maken we een instance factory class, InstanceBarFactory, met een fabrieksmethode die een argument accepteert en een Bar Boon:

openbare klasse InstanceBarFactory {openbare balk createInstance (tekenreeksnaam) {retourneer nieuwe balk (naam); }}

Ten slotte voegen we een constructor-arg element aan onze Bar bonen definitie:

We kunnen ons dan automatisch bedraden Bar boon op dezelfde manier als we deden voor onze Foo Boon:

@RunWith (SpringJUnit4ClassRunner.class) @ContextConfiguration ("/ factorymethod / instance-bar-config.xml") openbare klasse InstanceBarFactoryIntegrationTest {@Autowired private Bar-instantie; @ Test openbare ongeldig gegevenValidInstanceFactoryConfig_whenCreateInstance_thenNameIsCorrect () {assertNotNull (instantie); assertEquals ("someName", instance.getName ()); }}

3. Statische fabrieksmethode

We kunnen Spring ook configureren om een ​​statische methode als fabrieksmethode te gebruiken.

Hoewel fabrieksmethoden de voorkeur verdienen, kan deze techniek nuttig zijn als we bestaande, verouderde statische methoden hebben die de gewenste bonen produceren. Als een fabrieksmethode bijvoorbeeld een singleton retourneert, kunnen we Spring configureren om deze singleton factory-methode te gebruiken.

Net als bij bijvoorbeeld factory-methoden, kunnen we statische methoden met en zonder argumenten configureren.

3.1. Zonder argumenten

Met behulp van onze Foo klasse als onze gewenste boon, we kunnen een klasse maken, SingletonFooFactory, dat omvat een createInstance factory-methode die een singleton-exemplaar van Foo:

openbare klasse SingletonFooFactory {privé statische laatste Foo INSTANCE = nieuwe Foo (); openbare statische Foo createInstance () {terugkeer INSTANCE; }}

Deze keer, we hoeven maar één boon te maken. Deze boon heeft slechts twee attributen nodig:

  1. klasse - verklaart onze fabrieksklasse (SingletonFooFactory)
  2. fabrieksmethode - verklaart de statische fabrieksmethode (createInstance)

Als we dit toepassen op onze Spring XML-configuratie, krijgen we:

Ten slotte autowire onze Foo boon met dezelfde structuur als voorheen:

@RunWith (SpringJUnit4ClassRunner.class) @ContextConfiguration ("/ factorymethod / static-foo-config.xml") openbare klasse SingletonFooFactoryIntegrationTest {@Autowired private Foo singleton; @Test openbare ongeldig gegevenValidStaticFactoryConfig_whenCreateInstance_thenInstanceIsNotNull () {assertNotNull (singleton); }}

3.2. Met argumenten

Terwijl we moeten het veranderen van de status van statische objecten - zoals onze singleton - indien mogelijk vermijdenkunnen we nog steeds argumenten doorgeven aan onze statische fabrieksmethode.

Om dit te doen, maken we een nieuwe fabrieksmethode die onze gewenste argumenten accepteert:

openbare klasse SingletonBarFactory {privé statische laatste balk INSTANCE = nieuwe balk ("naamloos"); openbare statische balk createInstance (String naam) {INSTANCE.setName (naam); terug INSTANCE; }}

Daarna configureren we Spring om het gewenste argument door te geven met behulp van de constructor-arg element:

Ten slotte autowire onze Bar boon met dezelfde structuur als voorheen:

@RunWith (SpringJUnit4ClassRunner.class) @ContextConfiguration ("/ factorymethod / static-bar-config.xml") openbare klasse SingletonBarFactoryIntegrationTest {@Autowired private Bar-instantie; @Test openbare ongeldig gegevenValidStaticFactoryConfig_whenCreateInstance_thenNameIsCorrect () {assertNotNull (instantie); assertEquals ("someName", instance.getName ()); }}

4. Conclusie

In dit artikel hebben we gekeken hoe u Spring configureert om instance- en statische fabrieksmethoden te gebruiken - zowel met als zonder argumenten.

Hoewel het maken van bonen via constructor en veldinjectie vaker voorkomt, kunnen fabrieksmethoden handig zijn voor complexe aanmaakstappen en legacy-code.

De code die in dit artikel wordt gebruikt, is te vinden op GitHub.


$config[zx-auto] not found$config[zx-overlay] not found