笔记:Spring Beans 基于XML的三种自动装配方式:byName、byType、Constructor

  • 1. 在不使用自动装配的情况下
  • 2. byName
  • 2.1 byName的自动装配方式
  • 2.2 运行结果
  • 2.3 注意
  • 3. byType
  • 3.1 byType 的自动装配方式
  • 3.2 运行结果
  • 3.3 注意
  • 4. Constructor
  • 4.1 Constructor的自动装配方式
  • 4.2 运行结果
  • 总结


首先,定义 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 运行结果

springbootxml文件beans spring beans.xml_java

2.3 注意

  • 在使用自动装配的类中必须包含 set函数
  • 在使用 byName进行装配时,TextEditor必须包含一个无参构造器或不含构造器。如果只包含有参构造器,spring默认通过构造器注入属性,name属性必须通过构造器注入,使用<property>注入会报错
  • springbootxml文件beans spring beans.xml_构造器_02

  • 如果 id和 类的属性名称不匹配时,编译时不会报错,但运行时会抛出异常。如将 SpellChecker的配置文件改为:
<bean id="spellChecker" class="spring5.automatic.SpellChecker"></bean>

会抛出异常

springbootxml文件beans spring beans.xml_spring_03


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属性为 SpellCheckerbean,而不是查找id="spellChecker")。如果找到匹配项,同样通过```set函数``注入这些 beans,否则,它将抛出异常。

3.2 运行结果

springbootxml文件beans spring beans.xml_spring_04

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 运行结果

springbootxml文件beans spring beans.xml_java_05


总结

  • byName 和 byType 的装配方式较为相似,都是通过 set函数 进行属性注入,只是byName是通过id属性进行匹配,而byType是通过class属性进行匹配。
  • constructor 的自动装配很简单,记得加上构造器就行。