Spring——Bean的自动装配

本文介绍了Spring自动装配,它是满足bean依赖的方式,可在xml或Java中显示配置,也有隐式自动装配。重点讲解了ByName和byType两种自动装配方式,ByName需bean的id与set方法值对应,byType需bean的类型全局唯一。

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

  • 自动装配是Spring满足bean依赖一种方式
  • Spring会在上下文中自动寻找, 并自动给bean装配属性

在Spring中有三种装配的方式
  1. 在xml中显示的配置

  2. 在java中显示配置

  3. 隐式的自动装配bean [重要]

1. 测试


1. 环境搭建 -- 一个人有两个宠物

pojo实体类

Cat

package com.jean.pojo;

public class Cat {
    public void shout(){
        System.out.println("miao~");
    }
}

Dog

package com.jean.pojo;

public class Dog {
    public void shout(){
        System.out.println("wang~");
    }
}


People

package com.jean.pojo;

public class People {
    private Cat cat;
    private Dog dog;
    private String name;

    @Override
    public String toString() {
        return "People{" +
                "cat=" + cat +
                ", dog=" + dog +
                ", name='" + name + '\'' +
                '}';
    }

    public Cat getCat() {
        return cat;
    }

    public void setCat(Cat cat) {
        this.cat = cat;
    }

    public Dog getDog() {
        return dog;
    }

    public void setDog(Dog dog) {
        this.dog = dog;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public People() {
    }

    public People(Cat cat, Dog dog, String name) {
        this.cat = cat;
        this.dog = dog;
        this.name = name;
    }
}

resource
beans.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"
       xmlns:lang="http://www.springframework.org/schema/lang"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/lang
        https://www.springframework.org/schema/lang/spring-lang.xsd">

  <bean id="cat" class="com.jean.pojo.Cat"/>
  <bean id="dog" class="com.jean.pojo.Dog"/>

    <bean id="people" class="com.jean.pojo.People">
        <property name="name" value="张泽熙"/>
        <property name="dog" ref="dog"/>
        <property name="cat" ref="cat"/>
    </bean>

</beans>


测试类

import com.jean.pojo.People;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MyTest {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        People people = context.getBean("people", People.class);
//        让狗🐕叫
        System.out.print("让狗🐕叫");
        people.getDog().shout();
//        让猫🐱叫
        System.out.print("让猫🐱叫");
        people.getCat().shout();
    }
}

2. ByName自动装配

我们之前是手动引入
现在使用 autowire=“byName” 就可以实现自动装配

它的原理是:
byName: 会自动在容器上下文中查找, 和自己对象set方法后面的值对应的beanid;

<?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:lang="http://www.springframework.org/schema/lang"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/lang
        https://www.springframework.org/schema/lang/spring-lang.xsd">

  <bean id="cat" class="com.jean.pojo.Cat"/>
  <bean id="dog" class="com.jean.pojo.Dog"/>

<!--
byName: 会自动装配在容器上下文中查找, 和自己对象set方法后面的值对应 beanId;
-->
    <bean id="people" class="com.jean.pojo.People" autowire="byName">
        <property name="name" value="张泽熙"/>
<!--        <property name="dog" ref="dog"/>-->
<!--        <property name="cat" ref="cat"/>-->
    </bean>

</beans>

此时byName就去自动查找我们People实体类下的set方法后面的值对应的beanid[cat/dog]:

public void setCat(Cat cat) {
        this.cat = cat;
    }

    public void setDog(Dog dog) {
        this.dog = dog;
    }

如果把beans.xml里Dog注册的名字改为dog222他就找不到了, 因为我们Set方法后没有对应的dog222的方法值

<?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:lang="http://www.springframework.org/schema/lang"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/lang
        https://www.springframework.org/schema/lang/spring-lang.xsd">

  <bean id="cat" class="com.jean.pojo.Cat"/>
<!--  <bean id="dog" class="com.jean.pojo.Dog"/>-->
  <bean id="dog222" class="com.jean.pojo.Dog"/>

<!--
byName: 会自动装配在容器上下文中查找, 和自己对象set方法后面的值对应 beanId;
-->
    <bean id="people" class="com.jean.pojo.People" autowire="byName">
        <property name="name" value="张泽熙"/>
<!--        <property name="dog" ref="dog"/>-->
<!--        <property name="cat" ref="cat"/>-->
    </bean>

</beans>

3. byType自动装配

如我们把 autowire=“byName” 改为: autowire=“byType”

<?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:lang="http://www.springframework.org/schema/lang"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/lang
        https://www.springframework.org/schema/lang/spring-lang.xsd">

  <bean id="cat" class="com.jean.pojo.Cat"/>
<!--  <bean id="dog" class="com.jean.pojo.Dog"/>-->
  <bean id="dog222" class="com.jean.pojo.Dog"/>

<!--
byName: 会自动装配在容器上下文中查找, 和自己对象set方法后面的值对应 beanId;
-->
    <bean id="people" class="com.jean.pojo.People" autowire="byName">
        <property name="name" value="张泽熙"/>
<!--        <property name="dog" ref="dog"/>-->
<!--        <property name="cat" ref="cat"/>-->
    </bean>

</beans>

我们Dog id写为dog222就可以找到…? 那么这是为什么呢?
刚才byName不行byType就可以了呢?
因为:

byType: 会自动在容器上下文中查找, 和自己对象属性类型相同的bean

当然byType也有自己的弊端它需要保持自己的全局唯一, 如:
beans.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"
       xmlns:lang="http://www.springframework.org/schema/lang"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/lang
        https://www.springframework.org/schema/lang/spring-lang.xsd">

  <bean id="cat" class="com.jean.pojo.Cat"/>
  <bean id="dog" class="com.jean.pojo.Dog"/>
  <bean id="dog222" class="com.jean.pojo.Dog"/>

<!--
byName: 会自动装配在容器上下文中查找, 和自己对象set方法后面的值对应 beanId;
-->
    <bean id="people" class="com.jean.pojo.People" autowire="byType">
        <property name="name" value="张泽熙"/>
<!--        <property name="dog" ref="dog"/>-->
<!--        <property name="cat" ref="cat"/>-->
    </bean>

</beans>


我们配置了两个Dog测试它直接就会报错, 不会帮你跑

byType必须保证它的类型全局唯一才可以自动装配

那如果我们把id直接去掉省略掉我们就可以使用byType测试跑起来了
比如:

<?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:lang="http://www.springframework.org/schema/lang"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/lang
        https://www.springframework.org/schema/lang/spring-lang.xsd">

  <bean class="com.jean.pojo.Cat"/>
  <bean class="com.jean.pojo.Dog"/>

<!--
byName: 会自动装配在容器上下文中查找, 和自己对象set方法后面的值对应 beanId;
-->
    <bean id="people" class="com.jean.pojo.People" autowire="byType">
        <property name="name" value="张泽熙"/>
<!--        <property name="dog" ref="dog"/>-->
<!--        <property name="cat" ref="cat"/>-->
    </bean>

</beans>

甚至不用给他命名字, 也可以使用type找到, 因为它是根据类型来的

自动装配基于上下文来的


小结:
  • byName的时候,需要保证所有bean的id唯一, 并且这个bean需要和自动注入的属性的set方法的值一致.
  • byType的时候,需要保证所有bean的class唯一, 并且这个bean需要和自动注入的属性类型一致.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值