Spring——自动装配

ops/2025/1/12 15:30:39/

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

Persion.java

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;}@Overridepublic String toString() {return "Person{" +"dog=" + dog +", cat=" + cat +", name='" + name + '\'' +'}';}
}

Dog.java

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

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方法

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

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

java">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 {@Testpublic 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/beanshttps://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttps://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.ppmy.cn/ops/149062.html

相关文章

Unity学习之UGUI(二)

六、Image 1、作用 图像控件&#xff0c;用于显示Sprite的关键组件&#xff0c;除了背景图等大图&#xff0c;一般都是使用Image来显示UI中的图片元素 2、主要参数 &#xff08;1&#xff09;Image Type——Sliced&#xff08;拉伸&#xff09; Sliced-切片模式&#xff0c…

uniapp 微信小程序内嵌h5实时通信

描述&#xff1a; 小程序webview内嵌的h5需要向小程序实时发送消息&#xff0c;有人说postMessage可以实现&#xff0c;所以试验一下&#xff0c;结果是实现不了实时&#xff0c;只能在特定时机后退、组件销毁、分享时小程序才能接收到信息&#xff08;小程序为了安全等考虑做了…

oracle jdk17新版变回OTN 商用收费了

历史版本 https://www.oracle.com/java/technologies/javase/jdk17-archive-downloads.html 最新版 https://www.oracle.com/java/technologies/downloads/#java17 最新版页面有提示已经变回OTN JDK Development Kit 17.0.13 downloads The Oracle JDK 17 license changed in…

Vue3的reactive、ref、toRefs、toRef、toRaw 和 markRaw处理响应式数据区别

reactive reactive 用于创建一个响应式对象。它接受一个普通对象&#xff0c;并返回一个响应式对象&#xff08;Proxy实例&#xff09;。 import { reactive } from vue;// 创建一个reactive类型的响应式对象 const person reactive({name: panda,age: 18 });console.log(pe…

AI绘画:Midjourney和stable diffusion到底有什么区别?

Midjourney与Stable Diffusion的区别及选择指南 一、核心区别 二、应用场景与优势分析 三、如何选择&#xff1f; 四、AI配图 五、总结 Midjourney与Stable Diffusion的区别及选择指南 随着人工智能技术的飞速发展&#xff0c;AI绘画工具如雨后春笋般涌现&#xff0c;其中…

STM32Flash读写BUG,坑—————4字对齐

在 STM32 的 Flash 存储中&#xff0c;数据通常需要 4 字节对齐&#xff0c;这是由于其 Flash 存储的硬件设计和写入操作的限制决定的。 以下是更详细的原因与解释&#xff1a; 1. STM32 的 Flash 写入单位 STM32 的 Flash 通常以字&#xff08;Word&#xff0c;4 字节 32 位…

计算机网络安全 —— C# 使用谷歌身份验证器

一、Google Authenticator 基本概念 Google Authenticator是谷歌推出的一款动态口令工具&#xff0c;旨在决大家Google账户遭到恶意攻击的问题&#xff0c;在手机端生成动态口令后&#xff0c;在Google相关的服务登陆中除了用正常用户名和密码外&#xff0c;需要输入一次动态口…

AI赋能R-Meta分析核心技术:从热点挖掘到高级模型、助力高效科研与论文发表

Meta分析是针对某一科研问题&#xff0c;根据明确的搜索策略、选择筛选文献标准、采用严格的评价方法&#xff0c;对来源不同的研究成果进行收集、合并及定量统计分析的方法&#xff0c;现已广泛应用于农林生态&#xff0c;资源环境等方面&#xff0c;成为Science、Nature论文的…