我有一个名为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如何识别要调用的构造函数,因为两个提到的构造函数都得到了满足。
答案 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
的引用。