Spring DI having two constructors at the same time

5.9k Views Asked by At

This is an anti pattern, but I am curious what will actually happen.

If you explicitly define a no-args constructor and a constructor with an autowired parameter, how exactly will spring framework initialize it?

@Service
class Clazz {

    private MyBean myBean;

    public Clazz(){}

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

There are 2 best solutions below

0
Sergey Tselovalnikov On

The constructor marked by @Autowired will be used by spring. You can validate this by running the following code.

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);
  }
}

The code prints non-empty.

0
Oomph Fortuity On

On top of above answers, if there is single constructor declared without @autowire, spring uses same constructor for injection.

If there multiple constructors, then Spring uses constructor which is @autowired.

Mentioned in Spring Doc https://docs.spring.io/spring/docs/4.3.x/spring-framework-reference/htmlsingle/#beans-autowired-annotation

As of Spring Framework 4.3, an @Autowired annotation on such a constructor is no longer necessary if the target bean only defines one constructor to begin with. However, if several constructors are available, at least one must be annotated to teach the container which one to use