Please explain to me this (ambiguity) autowiring behavior through the constructor in Spring

First I provide a small piece of code, then I ask for an explanation.

public class A { private String msg; private B b; public A () { System.out.println("No argument constructor is called"); } public A (B b) { System.out.println("Parameterized constructor is called"); this.b = b; } // getters and setters } 

================================================

 <bean id="a" class="A" p:msg="hello" autowire="constructor"/> <bean id="b" class="B"/> 

================================================

OUTPUT:

The parameterized constructor is called

This is normal behavior and understandable.

================================================

Now I am adding a new bean definition of class B as shown below.

 <bean id="a" class="A" p:msg="hello" autowire="constructor"/> <bean id="b" class="B"/> <bean id="c" class="B"/> 

So, as far as I know, since autowiring through the constructor internally uses 'byType', therefore, it will give an exception regarding violation of the uniqueness of the bean, for example, this scenario occurs if I use autowire = "byType".

But, oddly enough, the conclusion is given below.

OUTPUT:

The argument constructor is not called

==========================================

However, note that if the default constructor is not specified in class A, the expected exception is expected. So, is this the default behavior in a Spring IoC container? If so, please kindly explain this to me in detail.

Thanks in advance.

The question is also available on LinkedIn ( Spring autowiring through constructor uncertainty )

+4
source share
2 answers

If the class has several constructors, any of which can be executed by auto-negotiation, then Spring will throw an exception, since it cannot decide which of the beans to be automatically wired.

http://www.studytrails.com/frameworks/spring/spring-auto-wire-constructor.jsp

So that means you need to select multiple Spring constructors. And Spring is so smart to choose the one that it can connect. So you only have a B bean, it uses a constructor with argument B. If you have two B beans, it cannot use this constructor due to more than one B, so it returns to the default constructor. You delete this constructor, you get an exception.

+1
source

I tried an example:

A.java

 package com.constructor; public class A { private String msg; private B b; public A () { System.out.println("No argument constructor is called"); } public A (B b) { System.out.println("Parameterized constructor is called"); this.b = b; } public String getMsg() { return msg; } public void setMsg(String msg) { this.msg = msg; } public B getB() { return b; } public void setB(B b) { this.b = b; } // getters and setters } 
0
source

Source: https://habr.com/ru/post/1491562/


All Articles