Java – constructor parameter parsing

I recently started working on version 3.2 I try to understand constructor parameter parsing in case dependencies are passed through constructor injection I created the following example

package com.springinaction.springidol;

public interface Performer {
    void perform();
}
package com.springinaction.springidol;

public class Juggler implements Performer {

    private int beanBags=3;
    private String name;

    public Juggler(){
    }

    public Juggler(String name,int beanBags){
        System.out.println("First constructor gets called");
        this.beanBags=beanBags;
        this.name=name;
    }

    public Juggler(int beanBags,String name){
        System.out.println("Second constructor gets called");
        this.beanBags=beanBags;
        this.name=name;
    }

    public void perform(){
    System.out.println("JUGGLING "+beanBags+name+" BEANBAGS");
    }
}

Please see the following example of the spring configuration file I use

<?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-3.0.xsd">

<bean id="duke" class="com.springinaction.springidol.Juggler">
    <constructor-arg value="Jinesh" />
    <constructor-arg value="77" />
</bean>

In the above scenario, the constructor called is the first constructor. But then I changed the XML file slightly and added the type attribute to the two parameters

<?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-3.0.xsd">

<bean id="duke" class="com.springinaction.springidol.Juggler">

<constructor-arg type="java.lang.String" value="Jinesh" />
<constructor-arg type="int" value="77" />

</bean>

</beans>

In the above example, the constructor called by spring is the second constructor I don't understand why spring decided to call the second constructor instead of the first constructor? In the above example, how does spring decide which constructor to call when we pass the type attribute?

Solution

Spring uses the constructorresolver instance to resolve the constructor used to instantiate the class It calls the autowireconstructor () method to determine it You can find the source code online Old version, here If you are active (using Maven), you can debug and complete it yourself

In this method, it attempts to use the argumentholder #gettypedifferenceweight() method to determine the difference between the specified parameter and the parameter in the controller In our example, it will return a value of 0 because the parameters match (even in a different order)

This value is compared with the mintypediffweight value (originally integer.max_value) If it is smaller, the current constructor being evaluated will get priority and this value will replace mintypediffweight This method continues through all class' constructors and compares with mintypediffweight again Since both constructors will be assigned a value of 0 (0 is not less than 0), the first one found is used

just right

Juggler.class.getDeclaredConstructors();

Returns a similar array

[public Test.Juggler(int,java.lang.String),public Test.Juggler(java.lang.String,int),public Test.Juggler()]

The second (declared) constructor appears first Getdeclaraedconstructors() method Javadoc declaration

So it's just a coincidence Because the parameter types match, spring chooses the first constructor it finds in the array

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>