笔记:Spring Beans 基于XML的三种自动装配方式:byName、byType、Constructor
首先,定义 SpellChecker、TextEditor 两个类用于测试
- SpellChecker
public class SpellChecker {
public SpellChecker() {
System.out.println("Inside SpellChecker constructor");
}
public void checkSpelling() {
System.out.println("Inside checkSpelling");
}
}
- TextEditor
public class TextEditor {
private SpellChecker spellChecker;
private String name;
public void spellCheck() {
spellChecker.checkSpelling();
}
}
- main主函数
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("bean3.xml");
TextEditor textEditor = context.getBean("textEditor", TextEditor.class);
textEditor.spellCheck();
System.out.println(textEditor.getName());
}
1. 在不使用自动装配的情况下
- xml 文件中应该为:
<bean id="spellChecker" class="spring5.automatic.SpellChecker"></bean>
<bean id="textEditor" class="spring5.automatic.TextEditor">
<property name="spellChecker" ref="spellChecker"></property>
<property name="name" value="nash"></property>
</bean>
2. byName
2.1 byName的自动装配方式
- 在bean文件中配置两个类的bean
<bean id="spellChecker" class="spring5.automatic.SpellChecker"></bean>
<bean id="textEditor" class="spring5.automatic.TextEditor" autowire="byName">
<property name="name" value="nash"></property>
</bean>
在 bean 中定义 autowire="byName"
后,spring
会尝试将该类的属性与配置文件中定义为相同名称(即 id
属性)的 beans 进行匹配和连接。如果找到匹配项,它将通过set函数
注入这些 beans,否则,将抛出异常。故在 TextEditor
中应有一个 setSpellChecker
函数,否则编译是不能通过的:
public void setSpellChecker(SpellChecker spellChecker) {
this.spellChecker = spellChecker;
}
2.2 运行结果
2.3 注意
-
在使用自动装配的类中必须包含
set函数
-
在使用
byName
进行装配时,TextEditor
必须包含一个无参构造器或不含构造器。如果只包含有参构造器,spring
默认通过构造器注入属性,name属性必须通过构造器注入,使用<property>
注入会报错
-
如果
id
和 类的属性名称不匹配时,编译时不会报错,但运行时会抛出异常。如将SpellChecker
的配置文件改为:
<bean id="spellChecker" class="spring5.automatic.SpellChecker"></bean>
会抛出异常
3. byType
3.1 byType 的自动装配方式
- 在bean文件中配置两个类的bean
<bean id="spellChecker" class="spring5.automatic.SpellChecker"></bean>
<bean id="textEditor" class="spring5.automatic.TextEditor" autowire="byType">
<property name="name" value="byType"></property>
</bean>
在 bean 中定义 autowire="byType"
后,spring会尝试去查找类型为 该类的属性的bean(即类 TextEditor
中有属性为 SpellChecker
,则spring 会查找 class
属性为 SpellChecker
的bean
,而不是查找id="spellChecker"
)。如果找到匹配项,同样通过```set函数``注入这些 beans,否则,它将抛出异常。
3.2 运行结果
3.3 注意
- 必须包含
set函数
- 因为
byType
查找的是class属性
,故bean的id属性
可以任意命名,不需要像byName一样id必须和类的属性名相同。即id="spell"
也是正确的
4. Constructor
4.1 Constructor的自动装配方式
- 在bean文件中配置两个类的bean
<bean id="spellChecker" class="spring5.automatic.SpellChecker"></bean>
<bean id="textEditor" class="spring5.automatic.TextEditor" autowire="constructor">
<constructor-arg ref="spellChecker"></constructor-arg>
<constructor-arg value="byConstructor"></constructor-arg>
</bean>
由构造器的自动装配较为简单,只需要 TextEditor
类中包含构造器即可
public TextEditor(SpellChecker spellChecker, String name) {
this.spellChecker = spellChecker;
this.name = name;
}
4.2 运行结果
总结
- byName 和 byType 的装配方式较为相似,都是通过 set函数 进行属性注入,只是byName是通过id属性进行匹配,而byType是通过class属性进行匹配。
- constructor 的自动装配很简单,记得加上构造器就行。