Статьи

Spring @Configuration и внедрение зависимостей bean-компонентов в качестве параметров метода

Один из способов, которыми Spring рекомендует внедрять взаимозависимости между компонентами, показан в следующем примере, скопированном из справочного руководства Spring здесь :

01
02
03
04
05
06
07
08
09
10
11
12
13
14
@Configuration
public class AppConfig {
 
 @Bean
 public Foo foo() {
  return new Foo(bar());
 }
 
 @Bean
 public Bar bar() {
  return new Bar("bar1");
 }
 
}

Итак, здесь bean-компонент `foo` вводится с зависимостью` bar`.

Однако существует один альтернативный способ внедрения зависимости, который не документирован должным образом, это просто взять зависимость как параметр метода `@ Bean` следующим образом:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
@Configuration
public class AppConfig {
 
 @Bean
 public Foo foo(Bar bar) {
  return new Foo(bar);
 }
 
 @Bean
 public Bar bar() {
  return new Bar("bar1");
 }
 
}

Здесь есть одна загвоздка: инъекция теперь осуществляется по типу, зависимость «bar» будет разрешаться сначала по типу, а если найдены дубликаты, то по имени:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
@Configuration
public static class AppConfig {
 
 @Bean
 public Foo foo(Bar bar1) {
  return new Foo(bar1);
 }
 
 @Bean
 public Bar bar1() {
  return new Bar("bar1");
 }
 
 @Bean
 public Bar bar2() {
  return new Bar("bar2");
 }
}

В приведенном выше примере зависимость `bar1` будет корректно введена. Если вы хотите быть более откровенным, аннотацию @Qualifer можно добавить в:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
@Configuration
public class AppConfig {
 
 @Bean
 public Foo foo(@Qualifier("bar1") Bar bar1) {
  return new Foo(bar1);
 }
 
 @Bean
 public Bar bar1() {
  return new Bar("bar1");
 }
 
 @Bean
 public Bar bar2() {
  return new Bar("bar2");
 }
}

Так что теперь вопрос о том, рекомендуется ли это вообще, я бы сказал, да для определенных случаев. Например, если бобовый бин был определен в другом классе @Configuration, способ внедрить эту зависимость будет следующим образом:

01
02
03
04
05
06
07
08
09
10
11
12
13
@Configuration
public class AppConfig {
 
 @Autowired
 @Qualifier("bar1")
 private Bar bar1;
 
 @Bean
 public Foo foo() {
  return new Foo(bar1);
 }
 
}

Я считаю, что подход метода метода проще:

1
2
3
4
5
6
7
8
9
@Configuration
public class AppConfig {
 
 @Bean
 public Foo foo(@Qualifier("bar1") Bar bar1) {
  return new Foo(bar1);
 }
 
}

Мысли?