我有一个名为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();
}
}我得到的输出如下:
测试杂耍杂耍3只豆袋
我的困惑是spring是如何识别要调用哪个构造函数的,因为上述两个构造函数都在满足。
发布于 2014-01-03 22:06:40
我试图模拟用例,对我来说,这完全取决于当多个构造函数满足时,通过反射返回构造函数的顺序。在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;
}
});
}因此,它纯粹基于排序,如果两个构造函数具有相同的权重,那么反射将如何返回构造函数。
发布于 2014-01-03 04:39:30
在这种情况下,Spring通过构造函数参数类型标识正确的bean。
当Spring执行自动装配时,发现
@Autowired(required=false)
public PoeticJuggler(Sonnet29 poem) {
...它读取构造函数参数类型com.springinaction.springidol.beans.Sonnet29。然后,它确定上下文中只有一个具有这样一个类的bean,因此它首先实例化sonnet29 bean,然后实例化poeticDuke,将引用传递给sonnect29作为concstuctor。
https://stackoverflow.com/questions/20896485
复制相似问题