@Autowired构造函数Spring

时间:2014-01-03 04:19:48

标签: java spring

我有一个名为PoeticJuggler的类,它有两个构造函数,如下所示:

 @Autowired(required=false)
    public PoeticJuggler(Sonnet29 poem)
    {
        super();
        this.poem=poem;
        System.out.println("Test to all");
    }

    @Autowired(required=false)
    public PoeticJuggler(TestConstJuggler tst)
    {
        super();
        this.poem=new Sonnet29();
        System.out.println("Test to Test Juggler");
    }
public PoeticJuggler(int beanBags,Poem poem)
    {
        super(beanBags);
        this.poem=poem;
    }

配置文件是这样的:

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

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


    <bean id="sonnet29" class="com.springinaction.springidol.beans.Sonnet29">
    </bean>

    <bean id="testDuke" class="com.springinaction.springidol.beans.TestConstJuggler">
    </bean>

    <bean id="poeticDuke" class="com.springinaction.springidol.beans.PoeticJuggler">
    </bean>

    <bean id="theStage" class="com.springinaction.springidol.beans.Stage" factory-method="getInstance">
    </bean>
</beans>

当我运行以下代码时:

public class BeanContext 
{
public static void main(String[] args) throws PerformanceException 
{
ApplicationContext ctx=new  ClassPathXmlApplicationContext("performancebean.xml");
Performer performer=(Performer)ctx.getBean("poeticDuke");
performer.perform();
}
}

我得到的输出为:

测试测试变戏法者    JUGGLING 3 BEANBAGS

我的困惑在于spring如何识别要调用的构造函数,因为两个提到的构造函数都得到了满足。

2 个答案:

答案 0 :(得分:2)

我试图模拟用例,对我来说,它纯粹取决于构造函数在多个构造函数满足时通过反射返回的顺序。在beanContext中尝试以下内容,让我们知道顺序。 注意**没有被授权者反射返回订单作为其在代码中的呈现。

Constructor<MainClass>[] methods = <yourClass>.class.getConstructors();
    for (int i = 0; i < methods.length; i++) {
        Class<?>[] types = methods[i].getParameterTypes();
        System.out.println("Constructor "+i);
        for (int j = 0; j < types.length; j++) {
            System.out.println("Param Type" + types[j].getName());
        }
    }

更新:     要更清楚地了解AutoWireUtils.sortConstructors中的排序逻辑。一旦spring使用下面的行获取所有构造函数,就会调用此方法

candidates = (mbd.isNonPublicAccessAllowed() ?
                        beanClass.getDeclaredConstructors() : beanClass.getConstructors());

AutoWireUtils.sortConstructors

public static void sortFactoryMethods(Method[] factoryMethods) {
    Arrays.sort(factoryMethods, new Comparator<Method>() {
        @Override
        public int compare(Method fm1, Method fm2) {
            boolean p1 = Modifier.isPublic(fm1.getModifiers());
            boolean p2 = Modifier.isPublic(fm2.getModifiers());
            if (p1 != p2) {
                return (p1 ? -1 : 1);
            }
            int c1pl = fm1.getParameterTypes().length;
            int c2pl = fm2.getParameterTypes().length;
            return (new Integer(c1pl)).compareTo(c2pl) * -1;
        }
    });
}

所以,它纯粹基于Sort,如果两个构造函数具有相同的权重,那么它就是反射如何返回构造函数的问题。

答案 1 :(得分:0)

在这种情况下,Spring通过构造函数参数类型识别正确的bean。

当Spring执行自动装配并找到

@Autowired(required=false)
public PoeticJuggler(Sonnet29 poem) {
...

它读取其构造函数参数类型com.springinaction.springidol.beans.Sonnet29。然后它确定在上下文中只有一个bean具有这样的类,因此它首先实例化sonnet29 bean然后实例化poeticDuke作为concstuctor arg传递对sonnect29的引用。