12

Spring docs:

Only one annotated constructor per-class can be marked as required, but multiple non-required constructors can be annotated.

If I have one autowired constructor, all is fine. If I have two or more autowired, but required=false annotated constructors, all is fine. But if I mix them in a way, such that there is one or more required=false constructor autowiring annotations and exactly one with the required=true, it throws an exception.

org.springframework.beans.factory.BeanCreationException: Invalid autowire-marked constructor: public annotationconfig.SomeBean(annotationconfig.AnotherBean). Found another constructor with 'required' Autowired annotation: public annotationconfig.SomeBean(annotationconfig.AnotherBean,annotationconfig.AnotherBean[])

Is this expected behavior? Am I missing something about how Spring dependency injection works? If this is normal, why is this a problem for Spring, why can't it handle a setup like this?

dsplynm
  • 593
  • 1
  • 8
  • 16
  • Could you post your source code? – Manuel Jordan Jul 13 '14 at 14:16
  • You can always fall back to annotating the field instead of the constructor marking the field annotation as required=false and lazy loading the variable. HTH – javamonkey79 Nov 13 '14 at 00:33
  • `@Component public class Account { private Card card; private AtmCard card1; @Autowired(required=true) public Account(Card card) { System.out.println(" in constructor"); this.card = card; } @Autowired(required=false) public Account(Card card, AtmCard card1) { System.out.println(" in setterr"); this.card = card; this.card1 = card1; } }` Error `Error creating bean with name 'account': Invalid autowire-marked constructor: public Account(Card,AtmCard). Found constructor with 'required' Autowired annotation already: public Account(Card)` Please help with this – Sagar Kharab May 29 '18 at 11:43

2 Answers2

14

I think the reason for that behavior is that if one of the constructors have @Autowired(required=true) then it must be called (because it is required) and because only one constructor can be called per object instantiation then what is the point of having other constructors with @Autowired(required=false)?

They won't be autowired anyway, because one of the constructors is already required and must be called. They can still be called without using Autowired mechanism, but in that case @Autowired(required=false) annotation is unnecessary.

mike_m
  • 1,526
  • 4
  • 14
  • 19
  • `@Component public class Account { private Card card; private AtmCard card1; @Autowired(required=true) public Account(Card card) { System.out.println(" in constructor"); this.card = card; } @Autowired(required=false) public Account(Card card, AtmCard card1) { System.out.println(" in setterr"); this.card = card; this.card1 = card1; } } ` Error `Error creating bean with name 'account': Invalid autowire-marked constructor: public Account(Card,AtmCard). Found constructor with 'required' Autowired annotation already: public Account(Card)` Please help witthis – Sagar Kharab May 29 '18 at 11:41
  • @mike_m So whats the difference of having only an constructor autowired vs an autowired required? – Maxrunner Dec 10 '19 at 15:17
  • @Maxrunner Default value of parameter **required** is **true**. So **@Autowired** and **@Autowired(required=true)** are the same. – mike_m Dec 11 '19 at 22:16
5

Spring 5 docs:

Only one annotated constructor per-class can be marked as required, but multiple non-required constructors can be annotated. In that case, each is considered among the candidates and Spring uses the greediest constructor whose dependencies can be satisfied, that is the constructor that has the largest number of arguments.

Although one constructor is required, spring might use the other constructors if dependancies are sesolved;