How is constructor chosen in spring for beans defined in xml with parent?

帅比萌擦擦* 提交于 2020-01-22 03:30:46

问题


I am working with Spring 3.1.0. I am trying to understand the way spring is reading its xml files. I am trying to understand how spring deals with ambiguous conditions in the bean definitions.

For example

I have Alarm.java

package com.anshbansal.alarm2;

public class Alarm {

    private String type;
    private int volume;
    private int hour;

    public Alarm() {
    }

    public Alarm(String type, int volume, int hour) {
        this.type = type;
        this.volume = volume;
        this.hour = hour;
    }

    public Alarm(String type, int volume) {
        this.type = type;
        this.volume = volume;
    }

    public Alarm(int volume, String type) {
        this.type = type;
        this.volume = volume;
    }

    public void setType(String type) {
        this.type = type;
    }

    public void setVolume(int volume) {
        this.volume = volume;
    }

    public void setHour(int hour) {
        this.hour = hour;
    }

    @Override
    public String toString() {
        return "Alarm{" +
                "type='" + type + '\'' +
                ", volume=" + volume +
                ", hour=" + hour +
                '}';
    }
}

My spring xml file alarm2.xml is as follows.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

       <bean id="propertyRandom" abstract="true">
              <constructor-arg value="23" type="int"/>
       </bean>


       <bean id="alarm1" class="com.anshbansal.alarm2.Alarm" parent="propertyRandom">
              <constructor-arg value="10" type="int"/>
              <constructor-arg value="Ringing" />
       </bean>


</beans>

There is ambiguity as it is not instantly clear which int will go into volume and which will go into hour. If I print I get the following

Alarm{type='Ringing', volume=23, hour=10}

So how does spring read the xml file to resolve which constructor to call? Parent first, then bean? Is it documented somewhere?

I know that there are ways like specifying index and name as attributes but I should also be aware about how to deal with such ambiguous conditions. That's why I am asking this.


回答1:


From spring documentation,

Constructor argument resolution matching occurs using the argument’s type. If no potential ambiguity exists in the constructor arguments of a bean definition, then the order in which the constructor arguments are defined in a bean definition is the order in which those arguments are supplied to the appropriate constructor when the bean is being instantiated.

I found the following answer which explains the spring behavior in selecting a constructor.

If you specify a constructor-arg without index, the greediest constructor that can be satisfied with the given arguments will be invoked (matching the arguments by type). In the case of java.io.File, this is the File(String parent, String child) constructor: Your String argument matches both by type, so the algorithm uses that constructor.

reference 1 reference 2

When inheriting from a parent, the constructor arguments get merged (same as merging property collections). In your case, after the merging the child bean constructor arguments will be

<constructor-arg value="23" type="int"/>
<constructor-arg value="10" type="int"/>
<constructor-arg value="Ringing" />

For ambiguous scenarios, use either the index or the constructor argument name.



来源:https://stackoverflow.com/questions/27241493/how-is-constructor-chosen-in-spring-for-beans-defined-in-xml-with-parent

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!