Spring - Beans 的自动装配

本文介绍了Spring框架中的自动装配功能,包括byName、byType及constructor三种模式,详细解释了每种模式的工作原理,并通过实例展示了如何简化XML配置。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Beans的自动连接(不知道怎么翻译好)
我们知道如何声明以及使用元素并且在xml配置中使用和元素注入

Spring 容器可以在不适用和元素的情况下,使用bean之间的协作关系自动连接,这样有助于减少XML配置文件的内容。

Autowiring Modes

自动装配模式
以下的自动装配模式让Spring容器再依赖注入中使用自动装配。需要在的元素定义中指明自动装配的模式。

NoModeDescription
1no这种是默认设置,表示没有自动装配,应该使用特殊的bean引用来装配。对于默认设置不需要做额外的事情。
2byName通过属性名称自动装配。Spring容器会在XML配置文件中查找对应属性名的bean来进行自动装配的。
3byType通过属性的数据类型自动装配。Spring容器会在XML中查找对应类型的bean来进行自动装配的。
4constructor和byType类似,但是这个type是构造参数中的type。如果不存在确切沟槽参数类型的bean,那么会导致fatal error。
5autodetectSpring首先会尝试通过构造的方式自动装配,如果没有生效,那么会尝试通过type自动装配

你可以使用byType或者constructor自动装配模式去装配数组和其他类型的集合。

Limitations with autowiring

自动装配的局限性在项目中大量使用就会很好理解,如果自动装配一般都没有被使用,开发者会对项目当中一个两个自动装配定义感到很困惑。虽然自动装配能够很有效的降低指定属性和构造参数的需求,但是你需要考虑到自动装配的局限性和缺点。

NoLimitationsDescription
1Overriding possibility你可以使用和设置指明依赖,但是这将会导致覆盖自动装配
2Primitive(原始) data types你不能自动装配所谓的简单属性,例如基元、字符串以及类
3Confusing nature自动装配不如明确装配,所以如果可能的话尽量明确装配

Spring Autowiring ‘byName’

此模式通过name属性进行装配的,Spring容器会在XML配置文件通过byName的方式查找bean,并自动装配。然后,它尝试将它的属性和配置文件中相同名称的beans进行匹配并装配,如果没有找到,则抛异常,如果找到则注入这些beans。

如果一个bean定义在配置文件中被设置成通过名称装配,并且它包含i 个spellChecker属性(当然它有一个setSpellChecker方法),Spring会查找一个名称为spellChecker的bean,并且使用它设置这个属性。你仍然可以使用<property>设置其他属性,下面的例子将演示这个情况:

Example

SpellChecker.java

package com.soygrow.AutoWiringByName;

public class SpellChecker {
    public SpellChecker() {
        System.out.println("Inside SpellChecker constructor." );
    }
    public void checkSpelling() {
        System.out.println("Inside checkSpelling." );
    }
}

TextEditor.java

package com.soygrow.AutoWiringByName;

public class TextEditor {
    private SpellChecker spellChecker;
    private String name;

    public void setSpellChecker( SpellChecker spellChecker ){
        this.spellChecker = spellChecker;
    }
    public SpellChecker getSpellChecker() {
        return spellChecker;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getName() {
        return name;
    }
    public void spellCheck() {
        spellChecker.checkSpelling();
    }
}

MainApp.java

package com.soygrow.AutoWiringByName;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MainApp {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("ByNameBeans.xml");
        TextEditor te = (TextEditor) context.getBean("textEditor");
        te.spellCheck();
    }
}

ByNameBeans.xml

<?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 = "textEditor" class = "com.soygrow.AutoWiringByName.TextEditor">
        <property name = "spellChecker" ref = "spellChecker" />
        <property name = "name" value = "Generic Text Editor" />
    </bean>

    <!-- Definition for spellChecker bean -->
    <bean id = "spellChecker" class = "com.soygrow.AutoWiringByName.SpellChecker"></bean>

</beans>

以上是正常情况下的XML配置文件,如果你是用autowiring byName的方式,那么你的配置文件如下所示:

<?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 = "textEditor" class = "com.soygrow.AutoWiringByName.TextEditor" autowire="byName">
        <property name = "name" value = "Generic Text Editor" />
    </bean>

    <!-- Definition for spellChecker bean -->
    <bean id = "spellChecker" class = "com.soygrow.AutoWiringByName.SpellChecker"></bean>

</beans>

如果一切正常,那么运行结果如下:

Inside SpellChecker constructor.
Inside checkSpelling.

Spring Autowiring ‘byType’

这种模式通过类型来完成自动装配。Spring容器会在XML配置文件中查找装配属性被设置成了byType的beans,如果它的type和配置文件中bean名称完成匹配,则尝试匹配连接属性,如果没有会抛出异常。

例如,如果一个bean定义在XML配置文件中被设置成了autowire byType,并且它包含一个spellChecker类型的spellChecker属性,Spring会查找一个名称为spellChecker的bean定义,并且使用它设置属性。你仍然可以使用<property>标签装配,下面通过例子来说明该问题:

Example

SpellChecker.java

package com.soygrow.AutoWiringByType;

public class SpellChecker {
    public SpellChecker(){
        System.out.println("Inside SpellChecker constructor." );
    }
    public void checkSpelling() {
        System.out.println("Inside checkSpelling." );
    }
}

TextEditor.java

package com.soygrow.AutoWiringByType;

public class TextEditor {
    private SpellChecker spellChecker;
    private String name;

    public void setSpellChecker( SpellChecker spellChecker ) {
        this.spellChecker = spellChecker;
    }
    public SpellChecker getSpellChecker() {
        return spellChecker;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getName() {
        return name;
    }
    public void spellCheck() {
        spellChecker.checkSpelling();
    }
}

MainApp.java

package com.soygrow.AutoWiringByType;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MainApp {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("ByTypeBeans.xml");
        TextEditor te = (TextEditor) context.getBean("textEditor");
        te.spellCheck();
    }
}

ByTypeBeans.xml

<?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="textEditor" class="com.soygrow.AutoWiringByType.TextEditor">
        <property name="spellChecker" ref="spellChecker"/>
        <property name="name" value="Generic Text Editor"/>
    </bean>

    <bean id="spellChecker" class="com.soygrow.AutoWiringByType.SpellChecker"></bean>
</beans>

上面是正常的XML配置文件,如果你使用‘byType’,你的XML配置文件可以简化,如下所示:

<?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="textEditor" class="com.soygrow.AutoWiringByType.TextEditor" autowire="byType">
        <property name="name" value="Generic Text Editor"/>
    </bean>

    <bean id="spellChecker" class="com.soygrow.AutoWiringByType.SpellChecker"></bean>
</beans>

如果一切正常,运行结果如下:

Inside SpellChecker constructor.
Inside checkSpelling.

Spring Autowiring by Constructor

这种模式非常类似于byType,但是它适用于构造参数。当autowire属性在XML配置中被设置的情况下,Spring容器会自动查找对应的beans。Spring容器会使用配置文件中确切名称的bean尝试匹配和装配它的构造参数。如果找到匹配的,则注入对应的beans,否则会抛出异常。

如果一个bean的定义在XML被设置了通过构造的自动装配,并且它又一个SpellChecker类型的构造参数,Spring容器会查找一个名称叫做SpellChecker的bean,并且使用它设置构造参数。你仍然可以使用<constructor-arg>装配其他参数,下面的例子将说明该问题。

Example

SpellChecker.java

package com.soygrow.AutoWiringConstructor;

public class SpellChecker {
    public SpellChecker(){
        System.out.println("Inside SpellChecker constructor." );
    }
    public void checkSpelling(){
        System.out.println("Inside checkSpelling." );
    }
}

TextEditor.java

package com.soygrow.AutoWiringConstructor;

public class TextEditor {
    private SpellChecker spellChecker;
    private String name;

    public TextEditor( SpellChecker spellChecker, String name ) {
        this.spellChecker = spellChecker;
        this.name = name;
    }
    public SpellChecker getSpellChecker() {
        return spellChecker;
    }
    public String getName() {
        return name;
    }
    public void spellCheck() {
        spellChecker.checkSpelling();
    }
}

MainApp.java

package com.soygrow.AutoWiringConstructor;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MainApp {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("AutoWireConstructorBeans.xml");
        TextEditor te = (TextEditor) context.getBean("textEditor");
        te.spellCheck();
    }
}

AutoWireConstructorBeans.xml

<?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">

    <!-- Definition for textEditor bean -->
    <bean id = "textEditor" class = "com.soygrow.AutoWiringConstructor.TextEditor">
        <constructor-arg  ref = "spellChecker" />
        <constructor-arg  value = "Generic Text Editor"/>
    </bean>

    <!-- Definition for spellChecker bean -->
    <bean id = "spellChecker" class = "com.soygrow.AutoWiringConstructor.SpellChecker"></bean>
</beans>

上面是正常的XML配置文件,如果使用autowire,你的配置文件如下所示:

<?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">

    <!-- Definition for textEditor bean -->
    <bean id = "textEditor" class = "com.soygrow.AutoWiringConstructor.TextEditor" autowire="constructor">
        <constructor-arg  value = "Generic Text Editor"/>
    </bean>

    <!-- Definition for spellChecker bean -->
    <bean id = "spellChecker" class = "com.soygrow.AutoWiringConstructor.SpellChecker"></bean>
</beans>

如果一切正常,运行结果如下:

Inside SpellChecker constructor.
Inside checkSpelling.

分析

  • byName、byType和constructor三种种方式都可以简化XML配置文件
  • 设置autowire,可以实现自动装配,根据名称、类型或者构造的方式
  • 作为初学者,只要能看懂这种方式就好,为了便于理解,建议还是不要使用自动装配的方式,只是个人建议
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值