Spring DI, имеющий два конструктора одновременно - PullRequest
1 голос
/ 18 июня 2019

Это анти паттерн, но мне любопытно, что на самом деле произойдет.

Если вы явно определите конструктор без аргументов и конструктор с параметром autowired, как именно Spring Framework его инициализирует?

@Service
class Clazz {

    private MyBean myBean;

    public Clazz(){}

    @Autowired
    public Clazz(MyBean myBean){
        this.myBean = myBean;
    }
}

Ответы [ 3 ]

0 голосов
/ 18 июня 2019

Spring сначала выбирает конструктор по наибольшему количеству параметров

sortConstructors учитывают предпочтение открытых конструкторов и конструкторов с максимальным числом аргументов.

Значение Clazz(MyBean myBean)

Это используемый компаратор :

(e1, e2) -> {
    int result = Boolean.compare(Modifier.isPublic(e2.getModifiers()), Modifier.isPublic(e1.getModifiers()));
    return result != 0 ? result : Integer.compare(e2.getParameterCount(), e1.getParameterCount());
0 голосов
/ 18 июня 2019

Вдобавок к ответам выше, если есть единственный конструктор, объявленный без @autowire, Spring использует тот же конструктор для инъекции.

Если существует несколько конструкторов, Spring использует конструктор @ autowired.

Упоминается в Spring Doc https://docs.spring.io/spring/docs/4.3.x/spring-framework-reference/htmlsingle/#beans-autowired-annotation

Начиная с Spring Framework 4.3, аннотация @Autowired для такого конструктор больше не нужен, если целевой бин определяет только один конструктор для начала. Однако, если несколько конструкторов доступно, по крайней мере один должен быть аннотирован, чтобы научить контейнер, который один для использования

0 голосов
/ 18 июня 2019

Конструктор, помеченный @Autowired, будет использоваться весной. Вы можете проверить это, запустив следующий код.

public class Main {
  @Component
  static class MyBean {}

  @Service
  static class Clazz {
    private MyBean myBean;

    public Clazz(){
      System.out.println("empty");
    }

    @Autowired
    public Clazz(MyBean myBean){
      this.myBean = myBean;
      System.out.println("non-empty");
    }
  }

  @Component
  @ComponentScan("my.package")
  private static class Configuration {
  }

  public static void main(String[] args) {
    var ctx = new AnnotationConfigApplicationContext();
    ctx.register(Configuration.class);
    ctx.refresh();
    ctx.getBean(Clazz.class);
  }
}

Код печатает non-empty.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...