我正在尝试从Pro Spring 5书中学习Spring。
以下是我在自动装配中不了解的示例:
<?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="fooOne" class="com.apress.prospring5.ch3.xml.Foo"/>
<bean id="barOne" class="com.apress.prospring5.ch3.xml.Bar"/>
<bean id="targetByName" autowire="byName" class="com.apress.prospring5.ch3.xml.Target"
lazy-init="true"/>
<bean id="targetByType" autowire="byType" class="com.apress.prospring5.ch3.xml.Target"
lazy-init="true"/>
<bean id="targetConstructor" autowire="constructor"
class="com.apress.prospring5.ch3.xml.Target" lazy-init="true"/>
</beans>
Tarjet班
package com.apress.prospring5.ch3.xml;
import org.springframework.context.support.GenericXmlApplicationContext;
public class Target {
private Foo fooOne;
private Foo fooTwo;
private Bar bar;
public Target() {
}
public Target(Foo foo) {
System.out.println("Target(Foo) called");
}
public Target(Foo foo, Bar bar) {
System.out.println("Target(Foo, Bar) called");
}
public void setFooOne(Foo fooOne) {
this.fooOne = fooOne;
System.out.println("Property fooOne set");
}
public void setFooTwo(Foo foo) {
this.fooTwo = foo;
System.out.println("Property fooTwo set");
}
public void setBar(Bar bar) {
this.bar = bar;
System.out.println("Property bar set");
}
public static void main(String... args) {
GenericXmlApplicationContext ctx = new GenericXmlApplicationContext();
ctx.load("classpath:spring/app-context-03.xml");
ctx.refresh();
Target t = null;
System.out.println("Using byName:\n");
t = (Target) ctx.getBean("targetByName");
System.out.println("\nUsing byType:\n");
t = (Target) ctx.getBean("targetByType");
System.out.println("\nUsing constructor:\n");
t = (Target) ctx.getBean("targetConstructor");
ctx.close();
}
}
Foo类
package com.apress.prospring5.ch3.xml;
public class Foo {
}
酒吧等级
package com.apress.prospring5.ch3.xml;
public class Bar {
}
我不明白的地方:
<bean id="targetByName" autowire="byName" class="com.apress.prospring5.ch3.xml.Target"
lazy-init="true"/>
知道我们在bean定义中没有使用任何属性或构造函数注入的情况下,如何注入目标属性(fooOne,fooTwo,bar)?
通常我们应该有类似的东西:
<property name = "fooOne">
<bean id = "fooOne" class = "com.apress.prospring5.ch3.xml.Foo"/>
</property>
答案 0 :(得分:1)
<bean id="targetByName" autowire="byName" class="com.apress.prospring5.ch3.xml.Target"
lazy-init="true"/>
因为它将自动连线模式声明为“ byName ”,所以具有以下行为(取自docs):
按属性名称自动装配。春天找豆子一样 名称为需要自动装配的属性。例如,如果 bean定义被设置为按名称自动装配,并且包含一个母版 属性(即,它具有setMaster(..)方法),Spring会查找 名为master的bean定义,并使用它来设置属性。
这意味着是二传手注射。
回到您的示例,由于Target
具有以下设置方法,因此spring将进行以下注入:
public class Target {
// Find a bean which name is "fooOne" , and call this setter to inject
public void setFooOne(Foo fooOne) {}
// Find a bean which name is "fooTwo" , and call this setter to inject (As no beans called fooTwo in your example , it will be null)
public void setFooTwo(Foo foo) {}
//Find a bean which name is "bar" , and call this setter to inject (As no beans called bar in your example , it will be null)
public void setBar(Bar bar) {}
}
当然,如果bean的类型与setter参数的类型不匹配,则会发生异常。