当前位置: 首页 > article >正文

Spring——自动装配

假设一个场景:
一个人(Person)有一条狗(Dog)和一只猫(Cat),狗和猫都会叫,狗叫是“汪汪”,猫叫是“喵喵”,同时人还有一个自己的名字。
将上述场景 抽象出三个实体类:Person、Dog和Cat

Persion.java

package com.zbt.autowire.dto;

/**
 * @author
 * @createAt 2025/1/9 20:44
 */


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

    public Dog getDog() {
        return dog;
    }

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

    public Cat getCat() {
        return cat;
    }

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

    public String getName() {
        return name;
    }

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

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

Dog.java

package com.zbt.autowire.dto;

/**
 * @author
 * @createAt 2025/1/9 20:42
 */


public class Dog {
    public void shout(){
        System.err.println("小狗叫:wang~");
    }
}


Cat.java

package com.zbt.autowire.dto;

/**
 * @author
 * @createAt 2025/1/9 20:43
 */


public class Cat {
    public void shout(){
        System.err.println("小猫叫:miao~");
    }
}

手动装配

在配置文件中注入属性—这种方式为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="dog" class="com.zbt.autowire.dto.Dog"/>
    <bean id="cat" class="com.zbt.autowire.dto.Cat"/>
    <bean id="person" class="com.zbt.autowire.dto.Person">
        <property name="name" value="张三"/>
        <property name="cat" ref="cat"/>
        <property name="dog" ref="dog"/>
    </bean>
</beans>

通过配置文件 自动装配

bean标签有一个属性叫做 autowire 它配置的是自动装配方式

byName注入

通过配置的其他的bean的id自动匹配参数名,相同则注入(换种说法:将和属性名相同的Bean id 对应的对象当做值进行注入)

<?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="dog" class="com.zbt.autowire.dto.Dog"/>
    <bean id="cat" class="com.zbt.autowire.dto.Cat"/>
    <!--<bean id="person" class="com.zbt.autowire.dto.Person">
        <property name="name" value="张三"/>
        <property name="cat" ref="cat"/>
        <property name="dog" ref="dog"/>
    </bean>-->
    <bean id="person" class="com.zbt.autowire.dto.Person" autowire="byName">
        <property name="name" value="张三"/>
    </bean>
</beans>

上面的例子中,Person中有cat和dog 在配置文件中Cat和Dog类的Bean id也是cat和dog,此时可以通过在Person的Bean上设置**autowire=“byName”**自动将cat和dog注入到Person中
注意 如果需要被注入的bean的id与属性名不同则无法注入
例如下面这种情况就无法给Person注入dog

<?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="dog1" class="com.zbt.autowire.dto.Dog"/>
    <bean id="cat" class="com.zbt.autowire.dto.Cat"/>
    <!--<bean id="person" class="com.zbt.autowire.dto.Person">
        <property name="name" value="张三"/>
        <property name="cat" ref="cat"/>
        <property name="dog" ref="dog"/>
    </bean>-->
    <bean id="person" class="com.zbt.autowire.dto.Person" autowire="byName">
        <property name="name" value="张三"/>
    </bean>
</beans>

接下来我们在另一个包entity下在新建一个Cat类,同样也有一个shout方法

package com.zbt.autowire.entity;

/**
 * @author
 * @createAt 2025/1/9 21:09
 */


public class Cat {
public void shout(){
    System.err.println("entity里的Cat");
}
}

在配置文件中对两个Cat类的bean做如下配置

<?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="dog1" class="com.zbt.autowire.dto.Dog"/>
    <bean id="cat1" class="com.zbt.autowire.dto.Cat"/>
    <bean id="cat" class="com.zbt.autowire.entity.Cat"/>
    <!--<bean id="person" class="com.zbt.autowire.dto.Person">
        <property name="name" value="张三"/>
        <property name="cat" ref="cat"/>
        <property name="dog" ref="dog"/>
    </bean>-->
    <bean id="person" class="com.zbt.autowire.dto.Person" autowire="byName">
        <property name="name" value="张三"/>
    </bean>
</beans>

此时Person注入的cat对象为entity包下的Cat

编写如下测试代码可验证结果:

import com.zbt.autowire.dto.Person;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * @author
 * @createAt 2025/1/9 21:01
 */


public class MyTest {
    @Test
    public void testAutowire(){
        ApplicationContext context = new ClassPathXmlApplicationContext("beansAutowire.xml");
        Person person = context.getBean("person", Person.class);
        person.getCat().shout();
    }
}

控制台输出为
在这里插入图片描述
注意我划线部分的报错,意思是无法将entity下的Cat转换为dto下的Cat(因为Person类中的Cat类型为dto下的Cat,而注入的根据bean的id匹配到的是entity下的,所以报了这个错误)

byType注入

通过配置的其他的bean的calss设置的类自动匹配参数类型,相同则注入(换种说法:查找与属性类型相同的Bean对应的对象当做值进行注入)

<?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="dog1" class="com.zbt.autowire.dto.Dog"/>
    <bean id="cat" class="com.zbt.autowire.dto.Cat"/>
    <!--<bean id="person" class="com.zbt.autowire.dto.Person">
        <property name="name" value="张三"/>
        <property name="cat" ref="cat"/>
        <property name="dog" ref="dog"/>
    </bean>-->
    <bean id="person" class="com.zbt.autowire.dto.Person" autowire="byType">
        <property name="name" value="张三"/>
    </bean>
</beans>

上面的例子中,Person中有cat和dog 在配置文件中也配置了Cat和Dog类的Bean,此时可以通过在Person的Bean上设置**autowire=“byType”**自动将cat和dog注入到Person中,与Cat和Dog的Bean的id无关。

同时在配置文件中也配置entity.cat的bean

<?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="dog1" class="com.zbt.autowire.dto.Dog"/>
    <bean id="cat" class="com.zbt.autowire.dto.Cat"/>
    <bean id="cat1" class="com.zbt.autowire.entity.Cat"/>
    <!--<bean id="person" class="com.zbt.autowire.dto.Person">
        <property name="name" value="张三"/>
        <property name="cat" ref="cat"/>
        <property name="dog" ref="dog"/>
    </bean>-->
    <bean id="person" class="com.zbt.autowire.dto.Person" autowire="byType">
        <property name="name" value="张三"/>
    </bean>
</beans>

发现最终注入的还是dto下的Cat(可以通过上述的测试代码可以发现控制台输出的是:“小猫叫:miao~”而不是:“entity里的Cat”,可以验证结论)

弊端: 必须保证每个类只能在配置文件里配置一次,一个类多次被配置时无法使用byType自动装配

通过注解 自动装配(@Autowire 、@Resource)

需要在配置文件中导入约束(context — 共三个)并添加一项配置( context:annotation-config/) 才能支持注解的使用
context 约束:

  1. xmlns:context=“http://www.springframework.org/schema/context”
    2.xsi:schemaLocation下的:" http://www.springframework.org/schema/context"
    3.xsi:schemaLocation下的:" https://www.springframework.org/schema/context/spring-context.xsd"
<?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:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd">

    <context:annotation-config/>

</beans>

@Autowire

原理:

  1. Autowire注解优先通过byType方式匹配bean,byType匹配不到再通过byName匹配
  2. 为了防止Autowire匹配不到bean,经常将Autowire与Qualifire搭配使用 通过 @Qualifire(value=“配置文件中的bean id”) 指定要匹配的bean 的id(Autowire + Qualifire 等价于 Resource)

用法
写在属性名上一行或者set方法上一行即可自动装配
推荐写在属性名上一行,因为属性名上使用此注解后,可以省略set方法(前提是配置文件中配置了对应的bean)
autowire的require属性:默认为true 代表这个属性的值不能为null,如果@Autowire(require = false) 则代表这个属性可以为null

@Resource

@Resource是jdk自带的注解
它可以指定name(bean的id),如@Resource(name=“cat”)
在不指定name的情况下:先byName,后byType。与Autowire的正好相反
用法
写在属性名上一行或者set方法上一行即可自动装配
推荐写在属性名上一行,因为属性名上使用此注解后,可以省略set方法(前提是配置文件中配置了对应的bean)


http://www.kler.cn/a/488113.html

相关文章:

  • android源码编译后,为什么emulator一直黑屏或者停止android界面
  • [大模型]本地离线运行openwebui+ollama容器化部署
  • java通过ocr实现识别pdf中的文字
  • tdengine数据库使用java连接
  • 【可实战】Bug的判定标准、分类、优先级、定位方法、提交Bug(包含常见面试题)
  • MySQL - 子查询和相关子查询详解
  • C++笔记之`size_t`辨析
  • Untiy中如何嵌入前端页面,从而播放推流视频?
  • Colossal-AI:深度学习大规模分布式训练框架
  • 光伏风电新技术进展:迈向能源新时代
  • 如何在 Ubuntu 22.04 上安装和配置邮件服务器教程
  • 华晨宇新专辑《量变临界点》上线 开启自我觉知的音乐旅程
  • 灵活运用事务回滚,快捷处理多张数据表格
  • 14_Redis事务
  • 初学者关于对机器学习的理解
  • Go语言的循环实现
  • 基于 SpringBoot线上考试系统的设计与实现
  • java.lang.OutOfMemoryError: PermGen space报错处理
  • Autodl安装tensorflow2.10.0记录
  • Linux基本指令(1)
  • 【数据库】三、SQL语言
  • [IoT]物联网(IoT)网络的安全性
  • 量子技术的发展
  • ubuntu编译龙蜥6.6内核源码
  • Swin Transformer模型详解(附pytorch实现)
  • AAAI2023《Controllable Image Captioning via Prompting》