Създаване на пролетен боб чрез фабрични методи

1. Въведение

Фабричните методи могат да бъдат полезна техника за скриване на сложна логика за създаване в рамките на едно извикване на метод.

Въпреки че обикновено създаваме боб през пролетта, използвайки конструктор или инжектиране на поле, ние също можем да създадем пролет боб, използвайки фабрични методи .

В този урок ще се задълбочим в създаването на Spring фасул, използвайки както екземпляр, така и статични фабрични методи.

2. Инсталиран фабричен метод

Стандартно изпълнение на модела на фабричния метод е да се създаде метод на екземпляр, който връща желания боб.

Освен това можем да конфигурираме Spring, за да създадем желания боб със или без аргументи .

2.1. Без аргументи

Можем да създадем клас Foo, който представлява нашия създаден боб:

public class Foo {}

След това създаваме клас InstanceFooFactory, който включва фабричен метод createInstance , който създава нашия Foo bean:

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

След това конфигурираме Spring:

  1. Създайте боб за нашия фабричен клас ( InstanceFooFactory )
  2. Използвайте атрибута factory-bean , за да се позовете на нашия фабричен bean
  3. Използвайте атрибута factory-method за препратка към нашия фабричен метод ( createInstance )

Прилагайки това към Spring XML конфигурация, в крайна сметка получаваме:

И накрая, ние автоматично свързваме желания от нас зърна Foo . След това Spring ще създаде нашия боб, използвайки нашия фабричен метод 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. С аргументи

Също така можем да предоставим аргументи на нашия фабричен метод, като използваме конструктора-arg елемент в нашата конфигурация Spring.

Първо, ние създаваме клас, Bar , който използва аргумент:

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

След това създаваме фабричен клас на екземпляр, InstanceBarFactory , с фабричен метод, който приема аргумент и връща боб на Bar :

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

И накрая, добавяме конструктор-arg елемент към нашата дефиниция на Bean Bar :

След това можем автоматично да свързваме нашия бар боб по същия начин, както направихме за нашия боб 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. Статичен фабричен метод

Също така можем да конфигурираме Spring да използва статичен метод като фабричен метод.

Въпреки че фабричните методи на екземпляра трябва да бъдат предпочитани, тази техника може да бъде полезна, ако имаме съществуващи, наследени статични методи, които произвеждат желани зърна. Например, ако фабричен метод връща сингълтон, можем да конфигурираме Spring да използва този фабричен метод на сингълтон.

Подобно на фабричните методи на екземпляра, ние можем да конфигурираме статични методи със и без аргументи.

3.1. Без аргументи

Използвайки нашия клас Foo като желания от нас фасул, можем да създадем клас, SingletonFooFactory , който включва фабричен метод createInstance , който връща единичен екземпляр на Foo :

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

Този път трябва да създадем само един боб. Този боб изисква само два атрибута:

  1. class - декларира фабричния ни клас ( SingletonFooFactory )
  2. factory-method - декларира статичния фабричен метод ( createInstance )

Прилагайки това към нашата Spring XML конфигурация, получаваме:

И накрая, ние автоматично свързваме нашия зърно Foo, използвайки същата структура като преди:

@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. С аргументи

Въпреки че трябва да избягваме промяната на състоянието на статичните обекти - като нашия сингълтон - когато е възможно , все пак можем да предаваме аргументи на нашия статичен фабричен метод.

За целта създаваме нов фабричен метод, който приема желаните от нас аргументи:

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

След това конфигурираме Spring, за да предадем желания аргумент, използвайки конструктор-аргумент елемент:

И накрая, ние автоматично свързваме нашето зърно Bar, използвайки същата структура като преди:

@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. Заключение

В тази статия разгледахме как да конфигурираме Spring да използва екземпляри и статични фабрични методи - както с, така и без аргументи.

Въпреки че създаването на боб чрез конструктор и инжектиране на поле е по-често, фабричните методи могат да бъдат удобни за сложни стъпки на създаване и наследствен код.

Кодът, използван в тази статия, може да бъде намерен в GitHub.