Когда бин имеет зависимость от другого бина, мы вводим бин используя свойство setter или через конструктор.
Метод getter вернет нам заданную ссылку, но предположим, что вы хотите новый экземпляр зависимого компонента каждый раз, когда вы вызываете метод get, тогда вам, вероятно, придется следовать другому подходу.
В этой статье мы увидим пример внедрения метода с использованием атрибута lookup-method
.
зависимости
Добавьте следующие зависимости:
-
spring-core
-
spring-context
-
spring-beans
pom.xml:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
< project xmlns = "http://maven.apache.org/POM/4.0.0" xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" < modelVersion >4.0.0</ modelVersion > < groupId >com.javarticles.spring</ groupId > < artifactId >springLookupMethodExample</ artifactId > < version >0.0.1-SNAPSHOT</ version > < dependencies > < dependency > < groupId >org.springframework</ groupId > < artifactId >spring-core</ artifactId > < version >${spring.version}</ version > </ dependency > < dependency > < groupId >org.springframework</ groupId > < artifactId >spring-context</ artifactId > < version >${spring.version}</ version > </ dependency > < dependency > < groupId >org.springframework</ groupId > < artifactId >spring-beans</ artifactId > < version >${spring.version}</ version > </ dependency > </ dependencies > < properties > < spring.version >3.2.3.RELEASE</ spring.version > </ properties > </ project > |
Подходы метода инъекции
Как мы получаем новый экземпляр каждый раз, когда мы вызываем метод getter? Один из подходов состоит в том, чтобы определить зависимый компонент как прототип, а затем реализовать метод getter, который возвращает нам новый экземпляр, вызывающий applicationContext.getBean(beanId)
.
Проблема с этим подходом заключается в том, что теперь вы зависите от applicationContext
.
Второй подход — позволить контейнеру управлять внедрением метода. Метод getter может быть абстрактным, позволяя пружинить динамически подкласс класса, содержащего метод getter, и реализовывать его для возврата настроенного компонента. Таким образом, мы можем использовать один и тот же базовый класс и развертывать его по-разному, чтобы возвращать нам разные bean-компоненты без необходимости изменения кода.
Внедрение метода с использованием lookup-метода
Рассматриваемый метод не должен быть методом получения, но он должен быть методом, который возвращает что-то. В нашем примере PizzaShop
является абстрактным классом и имеет два метода makePizza
и makeVeggiesPizza()
которые возвращают нам вегетарианскую Pizza
.
PizzaShop:
1
2
3
4
5
6
|
package com.javarticles.spring; public abstract class PizzaShop { public abstract Pizza makePizza(); public abstract Pizza makeVeggiePizza(); } |
Как видите, наш пример очень прост. Pizza
есть статическая переменная count
которая увеличивается при создании нового экземпляра. Он имеет логический член isVeg
который будет истинным, если пицца вегетарианская.
Пицца:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
|
package com.javarticles.spring; import java.util.concurrent.atomic.AtomicLong; public class Pizza { private static AtomicLong count = new AtomicLong( 0 ); private boolean isVeg; public Pizza() { count.incrementAndGet(); } public String toString() { return "A new " + (isVeg ? "veggie" : "" ) + "Pizza, count(" + count.get() + ")" ; } public void setIsVeg( boolean veg) { isVeg = veg; } } |
Мы настроим makePizza
и makeVeggiePizza
как makeVeggiePizza
lookup-method
. У нас настраивается нормальная пицца и вегетарианская фасоль для пиццы. Каждый абстрактный метод будет иметь один элемент <lookup-method. Атрибут name
будет именем метода, а компонент будет указывать на настроенный компонент. Здесь мы настроили как pizza
и veggiePizza
pizza
как прототип бобов.
applicationContext.xml:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
|
<? xml version = "1.0" encoding = "UTF-8" ?> xsi:schemaLocation = "http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd" > < bean id = "pizzaShop" class = "com.javarticles.spring.PizzaShop" > < lookup-method name = "makePizza" bean = "pizza" /> < lookup-method name = "makeVeggiePizza" bean = "veggiePizza" /> </ bean > < bean id = "pizza" class = "com.javarticles.spring.Pizza" scope = "prototype" /> < bean id = "veggiePizza" class = "com.javarticles.spring.Pizza" scope = "prototype" > < property name = "isVeg" value = "true" /> </ bean > </ beans > |
Пусть снег проверит это. Сначала мы загрузим контекст и получим PizzaShop
компонент PizzaShop
. Далее мы сделаем вызовы pizzaShop.makePizza()
и pizzaShop.makeVeggiePizza()
.
SpringLookupMethodExample:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
package com.javarticles.spring; import org.springframework.context.support.ClassPathXmlApplicationContext; public class SpringLookupMethodExample { public static void main(String[] args) { ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext( "applicationContext.xml" ); try { PizzaShop pizzaShop = (PizzaShop) context.getBean( "pizzaShop" ); Pizza firstPizza = pizzaShop.makePizza(); System.out.println( "First Pizza: " + firstPizza); Pizza secondPizza = pizzaShop.makePizza(); System.out.println( "Second Pizza: " + secondPizza); Pizza veggiePizza = pizzaShop.makeVeggiePizza(); System.out.println( "Veggie Pizza: " + veggiePizza); } finally { context.close(); } } } |
Каждый раз, когда мы вызываем метод, он создает новый компонент Pizza
, мы видим, как увеличивается счетчик.
Выход:
1
2
3
|
First Pizza: A new Pizza, count(1) Second Pizza: A new Pizza, count(2) Veggie Pizza: A new veggiePizza, count(3) |
Скачать исходный код
Это был пример внедрения метода пружины с использованием атрибута lookup-method
. Вы можете скачать исходный код здесь: springLookupMethodExample.zip
Ссылка: | Spring lookup-method Пример от нашего партнера по JCG Рама Моккапати в блоге Java Articles |